merged changes from trunk into branch (RAVE-625)

git-svn-id: https://svn.apache.org/repos/asf/rave/branches/model_interfaces@1354135 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index b5f1cd1..2373ea8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,8 +59,8 @@
         <commons-codec.version>1.4</commons-codec.version>
         <icu4j.version>4.8.1.1</icu4j.version>
         <easymock.version>3.0</easymock.version>
-        <com.h2database.version>1.3.154</com.h2database.version>
-        <openjpa.version>2.1.1</openjpa.version>
+        <com.h2database.version>1.3.167</com.h2database.version>
+        <openjpa.version>2.2.0</openjpa.version>
         <org.openid4java.version>0.9.6</org.openid4java.version>
         <jersey-server.version>1.6</jersey-server.version>
         <jersey-spring.version>1.0</jersey-spring.version>
@@ -79,6 +79,8 @@
         <!-- Force maven-filesync-plugin rewrite the Eclipse FileSync plugin configuration with
             $mvn filesync:generate -Dmaven.filesync.override=true -->
         <maven.filesync.override>false</maven.filesync.override>
+        <jackson.version>1.8.1</jackson.version>
+
 
         <!-- default empty javaagent
         if needed you can specify it on the command line with -Djavaagent="..." -->
@@ -116,6 +118,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.rave</groupId>
+                <artifactId>rave-jpa</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.rave</groupId>
                 <artifactId>rave-web</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -285,6 +292,11 @@
             </exclusions>
             </dependency>
             <dependency>
+                <groupId>org.codehaus.jackson</groupId>
+                <artifactId>jackson-mrbean</artifactId>
+                <version>${jackson.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>com.google.inject.extensions</groupId>
                 <artifactId>guice-persist</artifactId>
                 <version>${guice.version}</version>
diff --git a/rave-components/pom.xml b/rave-components/pom.xml
index f37bb10..52a6c3d 100644
--- a/rave-components/pom.xml
+++ b/rave-components/pom.xml
@@ -37,6 +37,7 @@
     <modules>
         <module>rave-commons</module>
         <module>rave-core</module>
+        <module>rave-jpa</module>
         <module>rave-web</module>
     </modules>
     
diff --git a/rave-components/rave-commons/pom.xml b/rave-components/rave-commons/pom.xml
index b641e36..bfc7f28 100644
--- a/rave-components/rave-commons/pom.xml
+++ b/rave-components/rave-commons/pom.xml
@@ -117,4 +117,4 @@
         </dependency>
     </dependencies>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java b/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java
new file mode 100644
index 0000000..6c8ff80
--- /dev/null
+++ b/rave-components/rave-commons/src/main/java/org/apache/rave/model/ModelConverter.java
@@ -0,0 +1,10 @@
+package org.apache.rave.model;
+
+import org.springframework.core.convert.converter.Converter;
+
+/**
+ * Converts a source type to a target
+ */
+public interface ModelConverter<S,T> extends Converter<S,T> {
+    Class<S> getSourceType();
+}
diff --git a/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/AbstractJpaRepository.java b/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/AbstractJpaRepository.java
deleted file mode 100644
index 5c20eb6..0000000
--- a/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/AbstractJpaRepository.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.persistence.jpa;
-
-import org.apache.rave.persistence.BasicEntity;
-import org.apache.rave.persistence.Repository;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
-
-/**
- * Provides generic implementations of {@link org.apache.rave.persistence.Repository} methods
- */
-public abstract class AbstractJpaRepository<T extends BasicEntity> implements Repository<T> {
-
-    @PersistenceContext
-    protected EntityManager manager;
-
-    private final Class<? extends T> type;
-
-    protected AbstractJpaRepository(Class<? extends T> type) {
-        this.type = type;
-    }
-
-    @Override
-    public Class<? extends T> getType() {
-        return type;
-    }
-
-    @Override
-    public T get(long id) {
-        return manager.find(type, id);
-    }
-
-    @Override
-    @Transactional
-    public T save(T item) {
-        return saveOrUpdate(item.getEntityId(), manager, item);
-    }
-
-    @Override
-    @Transactional
-    public void delete(T item) {
-        manager.remove(item);
-    }
-}
diff --git a/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java b/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java
index a492517..980654f 100644
--- a/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java
+++ b/rave-components/rave-commons/src/main/java/org/apache/rave/persistence/jpa/util/JpaUtil.java
@@ -24,6 +24,7 @@
 import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 
+import org.apache.rave.exception.NotSupportedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.dao.IncorrectResultSizeDataAccessException;
@@ -95,4 +96,25 @@
         query.setFirstResult(offset).setMaxResults(pageSize);
         return query.getResultList();
     }
+
+    /**
+     * Clears an original list and adds all items from the passed in base type list
+     * @param target the list to replace
+     * @param newList the list to replace with
+     * @param clazz the target class
+     * @param <E> The base type
+     * @param <T> The target type
+     */
+    public static <E, T extends E> void clearAndAdd(List<T> target, List<E> newList, Class<T> clazz) {
+        target.clear();
+        if (newList != null) {
+            for (E e : newList) {
+                if (e.getClass().equals(clazz)) {
+                    target.add((T)e);
+                } else {
+                    throw new NotSupportedException("Cannot directly set list composed of non JPA Entities");
+                }
+            }
+        }
+    }
 }
diff --git a/rave-components/rave-commons/src/main/java/org/apache/rave/util/CollectionUtils.java b/rave-components/rave-commons/src/main/java/org/apache/rave/util/CollectionUtils.java
index dc0680e..da6196b 100644
--- a/rave-components/rave-commons/src/main/java/org/apache/rave/util/CollectionUtils.java
+++ b/rave-components/rave-commons/src/main/java/org/apache/rave/util/CollectionUtils.java
@@ -107,17 +107,27 @@
     }

 

     /**

-     * Converts the wildcard list to a typed list

+     * Workaround for compile time checking of list types.  Generics are not persisted through runtime.  The compile time

+     * type system will still check that the items are castable to the base type.

      * @param initial the wildcard list

      * @param <T> the type constraint for the target list

-     * @return the new, type constrained list

+     * @return if initial is null, null otherwise the new, type constrained list

      */

+    @SuppressWarnings("unchecked")

     public static <T> List<T> toBaseTypedList(List<? extends T> initial) {

-        List<T> list = new ArrayList<T>();

-        for(T f : initial) {

-            list.add(f);

-        }

-        return list;

+        return (List<T>)initial;

+    }

+

+    /**

+     * Workaround for compile time checking of list types.  Generics are not persisted through runtime.  The compile time

+     * type system will still check that the items are castable to the base type.

+     * @param initial the wildcard collection

+     * @param <T> the type constraint for the target collection

+     * @return if initial is null, null otherwise the new, type constrained collection

+     */

+    @SuppressWarnings("unchecked")

+    public static <T> Collection<T> toBaseTypedCollection(Collection<? extends T> initial) {

+        return (Collection<T>)initial;

     }

 

     /**

diff --git a/rave-components/rave-commons/src/test/java/org/apache/rave/persistence/jpa/AbstractJpaRepositoryTest.java b/rave-components/rave-commons/src/test/java/org/apache/rave/persistence/jpa/AbstractJpaRepositoryTest.java
deleted file mode 100644
index 45e120d..0000000
--- a/rave-components/rave-commons/src/test/java/org/apache/rave/persistence/jpa/AbstractJpaRepositoryTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.persistence.jpa;
-
-import org.apache.rave.persistence.BasicEntity;
-import org.apache.rave.persistence.Repository;
-import org.junit.Before;
-import org.junit.Test;
-
-import javax.persistence.EntityManager;
-
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.sameInstance;
-import static org.junit.Assert.assertThat;
-
-/**
- */
-public class AbstractJpaRepositoryTest {
-
-    private static final long ID = 1L;
-    private EntityManager manager;
-    private Repository<TestEntity> repository;
-
-    @Before
-    public void setup() {
-        manager = createNiceMock(EntityManager.class);
-        repository = new TestJpaRepository(manager);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void getType() {
-        assertThat((Class<TestEntity>) repository.getType(), is(equalTo(TestEntity.class)));
-    }
-
-    @Test
-    public void get() {
-        expect(manager.find(TestEntity.class, ID)).andReturn(new TestEntity(ID));
-        replay(manager);
-
-        TestEntity entity = repository.get(ID);
-        assertThat(entity.getEntityId(), is(equalTo(ID)));
-        verify(manager);
-    }
-
-    @Test
-    public void save_persist() {
-        TestEntity entity = new TestEntity(null);
-        manager.persist(entity);
-        expectLastCall();
-        replay(manager);
-
-        TestEntity result = repository.save(entity);
-        assertThat(result, is(sameInstance(entity)));
-        verify(manager);
-    }
-
-
-    @Test
-    public void save_merge() {
-        TestEntity entity = new TestEntity(ID);
-        expect(manager.merge(entity)).andReturn(new TestEntity(ID));
-        replay(manager);
-
-        TestEntity result = repository.save(entity);
-        assertThat(result, is(not(sameInstance(entity))));
-        verify(manager);
-    }
-
-
-    @Test
-    public void delete() {
-        TestEntity entity = new TestEntity(ID);
-        manager.remove(entity);
-        expectLastCall();
-        replay(manager);
-
-        repository.delete(entity);
-        verify(manager);
-    }
-
-
-    private class TestJpaRepository extends AbstractJpaRepository<TestEntity> {
-
-        protected TestJpaRepository(EntityManager manager) {
-            super(TestEntity.class);
-            this.manager = manager;
-        }
-    }
-
-    private class TestEntity implements BasicEntity{
-        private Long entityId;
-
-        private TestEntity(Long entityId) {
-            this.entityId = entityId;
-        }
-
-        @Override
-        public Long getEntityId() {
-            return entityId;
-        }
-
-        @Override
-        public void setEntityId(Long entityId) {
-            this.entityId = entityId;
-        }
-    }
-}
diff --git a/rave-components/rave-commons/src/test/java/org/apache/rave/util/CollectionUtilsTest.java b/rave-components/rave-commons/src/test/java/org/apache/rave/util/CollectionUtilsTest.java
index b7085df..5c54faf 100644
--- a/rave-components/rave-commons/src/test/java/org/apache/rave/util/CollectionUtilsTest.java
+++ b/rave-components/rave-commons/src/test/java/org/apache/rave/util/CollectionUtilsTest.java
@@ -191,6 +191,14 @@
     }

 

     @Test

+    public void toBaseTypedList_null() {

+        List<SubTestObject> list = null;

+

+        List<TestObject> down = CollectionUtils.toBaseTypedList((List<? extends TestObject>)list);

+        assertThat(down, is(nullValue()));

+    }

+

+    @Test

     public void addUniqueValues() {

         List<TestObject> source = new ArrayList<TestObject>();

         TestObject testObject1 = new TestObject("a", "b");

diff --git a/rave-components/rave-core/pom.xml b/rave-components/rave-core/pom.xml
index 4d8f116..c6660d8 100644
--- a/rave-components/rave-core/pom.xml
+++ b/rave-components/rave-core/pom.xml
@@ -79,10 +79,6 @@
             <artifactId>spring-context</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-orm</artifactId>
-        </dependency>
-        <dependency>
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-web</artifactId>
         </dependency>
@@ -101,18 +97,6 @@
             <version>20090211</version>
         </dependency>
 
-        <!--Persistence-->
-        <dependency>
-            <groupId>org.apache.openjpa</groupId>
-            <artifactId>openjpa</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
-            <scope>test</scope>
-        </dependency>
-
         <!-- Logging -->
         <dependency>
             <groupId>org.slf4j</groupId>
@@ -176,40 +160,5 @@
 
     <build>
         <defaultGoal>install</defaultGoal>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>openjpa-maven-plugin</artifactId>
-                <version>1.2</version>
-                <configuration>
-                    <includes>org/apache/rave/portal/model/*.class</includes>
-                    <excludes>org/apache/rave/portal/model/WidgetStatus.class</excludes>
-                    <addDefaultConstructor>true</addDefaultConstructor>
-                    <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>enhancer</id>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>enhance</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <exclusions>
-                            <exclusion>
-                                <groupId>xerces</groupId>
-                                <artifactId>xmlParserAPIs</artifactId>
-                            </exclusion>
-                        </exclusions>
-                        <groupId>org.apache.openjpa</groupId>
-                        <artifactId>openjpa</artifactId>
-                        <version>${openjpa.version}</version>
-                    </dependency>
-                </dependencies>
-            </plugin>
-        </plugins>
     </build>
 </project>
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java
index 0dd9a6f..5bd2644 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Address.java
@@ -1,172 +1,48 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
+import javax.xml.bind.annotation.XmlTransient;
 
 /**
  */
-@Entity
-@Table(name = "address")
-public class Address {
+@XmlTransient
+public interface Address {
+    String getCountry();
 
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "addressIdGenerator")
-    @TableGenerator(name = "addressIdGenerator", table = "RAVE_SHINDIG_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "address", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    void setCountry(String country);
 
-    @Basic
-    @Column(name = "country", length = 255)
-    private String country;
+    Float getLatitude();
 
-    @Basic
-    @Column(name = "latitude")
-    private Float latitude;
+    void setLatitude(Float latitude);
 
-    @Basic
-    @Column(name = "longitude")
-    private Float longitude;
+    Float getLongitude();
 
-    @Basic
-    @Column(name = "locality", length = 255)
-    private String locality;
+    void setLongitude(Float longitude);
 
-    @Basic
-    @Column(name = "postal_code", length = 255)
-    private String postalCode;
+    String getLocality();
 
-    @Basic
-    @Column(name = "region", length = 255)
-    private String region;
+    void setLocality(String locality);
 
-    @Basic
-    @Column(name = "street_address", length = 255)
-    private String streetAddress;
+    String getPostalCode();
 
-    @Basic
-    @Column(name = "qualifier", length = 255)
-    private String qualifier;
+    void setPostalCode(String postalCode);
 
-    @Basic
-    @Column(name = "formatted", length = 255)
-    private String formatted;
+    String getRegion();
 
-    @Basic
-    @Column(name = "primary_address")
-    private Boolean primary;
+    void setRegion(String region);
 
-    public Long getEntityId() {
-        return entityId;
-    }
+    String getStreetAddress();
 
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
+    void setStreetAddress(String streetAddress);
 
-    public String getCountry() {
-        return country;
-    }
+    String getQualifier();
 
-    public void setCountry(String country) {
-        this.country = country;
-    }
+    void setQualifier(String qualifier);
 
-    public Float getLatitude() {
-        return latitude;
-    }
+    String getFormatted();
 
-    public void setLatitude(Float latitude) {
-        this.latitude = latitude;
-    }
+    void setFormatted(String formatted);
 
-    public Float getLongitude() {
-        return longitude;
-    }
+    Boolean getPrimary();
 
-    public void setLongitude(Float longitude) {
-        this.longitude = longitude;
-    }
-
-    public String getLocality() {
-        return locality;
-    }
-
-    public void setLocality(String locality) {
-        this.locality = locality;
-    }
-
-    public String getPostalCode() {
-        return postalCode;
-    }
-
-    public void setPostalCode(String postalCode) {
-        this.postalCode = postalCode;
-    }
-
-    public String getRegion() {
-        return region;
-    }
-
-    public void setRegion(String region) {
-        this.region = region;
-    }
-
-    public String getStreetAddress() {
-        return streetAddress;
-    }
-
-    public void setStreetAddress(String streetAddress) {
-        this.streetAddress = streetAddress;
-    }
-
-    public String getQualifier() {
-        return qualifier;
-    }
-
-    public void setQualifier(String qualifier) {
-        this.qualifier = qualifier;
-    }
-
-    public String getFormatted() {
-        return formatted;
-    }
-
-    public void setFormatted(String formatted) {
-        this.formatted = formatted;
-    }
-
-    public Boolean getPrimary() {
-        return primary;
-    }
-
-    public void setPrimary(Boolean primary) {
-        this.primary = primary;
-    }
+    void setPrimary(Boolean primary);
 }
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/TagTest.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/ApplicationData.java
similarity index 70%
copy from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/TagTest.java
copy to rave-components/rave-core/src/main/java/org/apache/rave/portal/model/ApplicationData.java
index db2d9a2..ff9dc0e 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/TagTest.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/ApplicationData.java
@@ -16,23 +16,22 @@
  * specific language governing permissions and limitations

  * under the License.

  */

-

 package org.apache.rave.portal.model;

 

-import org.junit.Test;

+import javax.xml.bind.annotation.XmlTransient;

+import java.util.Map;

 

-import static junit.framework.Assert.assertEquals;

+@XmlTransient

+public interface ApplicationData {

+    Long getId();

+    void setId(Long id);

 

-/**

- * Test for {@link org.apache.rave.portal.model.Authority}

- */

-public class TagTest {

+    String getUserId();

+    void setUserId(String userId);

 

-    @Test

-    public void testAuthority() throws Exception {

-        Tag tag = new Tag();

-        tag.setKeyword("test");

-        assertEquals("test", tag.getKeyword());

+    String getAppUrl();

+    void setAppUrl(String appUrl);

 

-    }

+    Map<String, String> getData();

+    void setData(Map<String, String> data);

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Authority.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Authority.java
index 186012d..0fb0f26 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Authority.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Authority.java
@@ -1,165 +1,24 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
 import org.springframework.security.core.GrantedAuthority;
 
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.ManyToMany;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.PreRemove;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import java.io.Serializable;
-import java.util.ArrayList;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.Collection;
 
-/**
- * The {@link GrantedAuthority} a {@link User} can have
- */
-@Entity
-@Table(name = "granted_authority")
-@NamedQueries({
-        @NamedQuery(name = Authority.GET_BY_AUTHORITY_NAME, query = "SELECT a FROM Authority a WHERE a.authority = :authority"),
-        @NamedQuery(name = Authority.GET_ALL, query = "SELECT a FROM Authority a"),
-        @NamedQuery(name = Authority.GET_ALL_DEFAULT, query = "SELECT a FROM Authority a WHERE a.defaultForNewUser = true"),
-        @NamedQuery(name = Authority.COUNT_ALL, query = "SELECT COUNT(a) FROM Authority a")
-})
-public class Authority implements GrantedAuthority, BasicEntity, Serializable {
-
-    private static final long serialVersionUID = 463209366149842862L;
-
-    public static final String PARAM_AUTHORITY_NAME = "authority";
-    public static final String GET_BY_AUTHORITY_NAME = "Authority.GetByAuthorityName";
-    public static final String GET_ALL = "Authority.GetAll";
-    public static final String GET_ALL_DEFAULT = "Authority.GetAllDefault";
-    public static final String COUNT_ALL = "Authority.CountAll";
-
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "grantedAuthorityIdGenerator")
-    @TableGenerator(name = "grantedAuthorityIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "granted_authority", allocationSize = 1, initialValue = 1)
-    private Long entityId;
-
-    @Basic
-    @Column(name = "authority", unique = true)
-    private String authority;
-
-    @ManyToMany(mappedBy = "authorities", fetch = FetchType.LAZY)
-    private Collection<User> users;
-    
-    @Basic
-    @Column(name = "default_for_new_user")
-    private boolean defaultForNewUser;
-
-    /**
-     * Default constructor, needed for JPA
-     */
-    public Authority() {
-        this.users = new ArrayList<User>();
-    }
-
+@XmlTransient
+public interface Authority extends GrantedAuthority {
     @Override
-    public Long getEntityId() {
-        return entityId;
-    }
+    String getAuthority();
 
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
+    void setAuthority(String authority);
 
-    @Override
-    public String getAuthority() {
-        return authority;
-    }
+    boolean isDefaultForNewUser();
 
-    public void setAuthority(String authority) {
-        this.authority = authority;
-    }
-    
-    public boolean isDefaultForNewUser() {
-        return defaultForNewUser;
-    }    
-    
-    public void setDefaultForNewUser(boolean defaultForNewUser) {
-        this.defaultForNewUser = defaultForNewUser;
-    }    
+    void setDefaultForNewUser(boolean defaultForNewUser);
 
-    public Collection<User> getUsers() {
-        return users;
-    }
+    Collection<User> getUsers();
 
-    public void addUser(User user) {
-        if (!users.contains(user)) {
-            users.add(user);
-        }
-        if (!user.getAuthorities().contains(this)) {
-            user.addAuthority(this);
-        }
-    }
+    void addUser(User user);
 
-    public void removeUser(User user) {
-        if (users.contains(user)) {
-            users.remove(user);
-        }
-    }
-
-    @PreRemove
-    public void preRemove() {
-        for (User user : users) {
-            user.removeAuthority(this);
-        }
-        this.users = null;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        Authority authority = (Authority) o;
-
-        if (entityId != null ? !entityId.equals(authority.entityId) : authority.entityId != null) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return entityId != null ? entityId.hashCode() : 0;
-    }
+    void removeUser(User user);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Category.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Category.java
index be4fbe4..2196431 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Category.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Category.java
@@ -15,166 +15,33 @@
  */
 package org.apache.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-import org.codehaus.jackson.annotate.JsonIgnore;
-
-import javax.persistence.*;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.Date;
 import java.util.List;
 
 /**
  * A category for a widget.
  */
-@Entity
-@Table(name = "category")
-@XmlRootElement
-@NamedQueries({
-        @NamedQuery(name = Category.GET_ALL, query = "select c from Category c order by c.text")
-})
-public class Category implements BasicEntity, Serializable {
-    // constants for JPA query names
-    public static final String GET_ALL = "Category.getAll";
+@XmlTransient
+public interface Category {
+    public Long getId();
+    public void setId(Long id);
 
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "categoryIdGenerator")
-    @TableGenerator(name = "categoryIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-                    valueColumnName = "SEQ_COUNT", pkColumnValue = "category",
-                    allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    public String getText();
+    public void setText(String text);
 
-    @Basic
-    @Column(name = "text", unique = true)
-    private String text;
+    public User getCreatedUser();
+    public void setCreatedUser(User createdUser);
 
-    @OneToOne(fetch=FetchType.EAGER)
-    @JoinColumn(name="created_user_id")
-    private User createdUser;
+    public Date getCreatedDate();
+    public void setCreatedDate(Date createdDate);
 
-    @Basic
-    @Column(name ="created_date")
-    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
-    private Date createdDate;
+    public User getLastModifiedUser();
+    public void setLastModifiedUser(User lastModifiedUser);
 
+    public Date getLastModifiedDate();
+    public void setLastModifiedDate(Date lastModifiedDate);
 
-    @OneToOne(fetch=FetchType.EAGER)
-    @JoinColumn(name="last_modified_user_id")
-    private User lastModifiedUser;
-
-    @Basic
-    @Column(name ="last_modified_date")
-    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
-    private Date lastModifiedDate;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(name="widget_category",
-               joinColumns=@JoinColumn(name="category_id", referencedColumnName = "entity_id"),
-               inverseJoinColumns=@JoinColumn(name="widget_id", referencedColumnName = "entity_id")
-    )
-    @OrderBy("title")
-    private List<Widget> widgets;
-
-    public Category() {
-
-    }
-
-    public Category(Long entityId, String text, User createdUser, Date createdDate, User lastModifiedUser, Date lastModifiedDate) {
-        this.entityId = entityId;
-        this.text = text;
-        this.createdUser = createdUser;
-        this.createdDate = createdDate;
-        this.lastModifiedUser = lastModifiedUser;
-        this.lastModifiedDate = lastModifiedDate;
-    }
-
-    @Override
-    public Long getEntityId() {
-        return entityId;
-    }
-
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-
-    public String getText() {
-        return text;
-    }
-
-    public void setText(String text) {
-        this.text = text;
-    }
-
-    public User getCreatedUser() {
-        return createdUser;
-    }
-
-    public void setCreatedUser(User createdUser) {
-        this.createdUser = createdUser;
-    }
-
-    public Date getCreatedDate() {
-        return createdDate;
-    }
-
-    public void setCreatedDate(Date createdDate) {
-        this.createdDate = createdDate;
-    }
-
-    public User getLastModifiedUser() {
-        return lastModifiedUser;
-    }
-
-    public void setLastModifiedUser(User lastModifiedUser) {
-        this.lastModifiedUser = lastModifiedUser;
-    }
-
-    public Date getLastModifiedDate() {
-        return lastModifiedDate;
-    }
-
-    public void setLastModifiedDate(Date lastModifiedDate) {
-        this.lastModifiedDate = lastModifiedDate;
-    }
-
-    @JsonIgnore
-    public List<Widget> getWidgets() {
-        return widgets;
-    }
-
-    public void setWidgets(List<Widget> widgets) {
-        this.widgets = widgets;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Category other = (Category) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 79 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        return "Category{" +
-                "entityId=" + entityId +
-                ", text='" + text + '\'' +
-                '}';
-    }
-}
+    public List<Widget> getWidgets();
+    public void setWidgets(List<Widget> widgets);
+}
\ No newline at end of file
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Group.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Group.java
index 7fdfb2a..82d2cb1 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Group.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Group.java
@@ -18,89 +18,27 @@
  */
 package org.apache.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.*;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.List;
 
 /**
- * Represents a group in the social database. The assumption in this object is that groups are
- * associated with individuals and are used by those individuals to manage people.
+ *
  */
-@Entity
-@Table(name = "groups")
-@NamedQueries(
-        @NamedQuery(name = Group.FIND_BY_TITLE, query="select g from Group g where g.title = :groupId")
-)
-public class Group implements BasicEntity {
+@XmlTransient
+public interface Group {
+    Person getOwner();
 
-    public static final String FIND_BY_TITLE = "Group.findById";
-    public static final String GROUP_ID_PARAM = "groupId";
+    void setOwner(Person owner);
 
-    /**
-     * The internal object ID used for references to this object. Should be generated by the
-     * underlying storage mechanism
-     */
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "groupIdGenerator")
-    @TableGenerator(name = "groupIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "groups", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    String getDescription();
 
-    @Basic
-    @Column(name = "title", unique = true)
-    private String title;
+    void setDescription(String description);
 
-    @Basic
-    @Column(name = "description")
-    private String description;
+    List<Person> getMembers();
 
-    @ManyToOne
-    @JoinColumn(name = "owner_id", referencedColumnName = "entity_id")
-    private Person owner;
+    void setMembers(List<Person> members);
 
-    @ManyToMany(fetch = FetchType.EAGER, mappedBy = "groups")
-    private List<Person> members;
+    String getTitle();
 
-    public Person getOwner() {
-        return owner;
-    }
-
-    public void setOwner(Person owner) {
-        this.owner = owner;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public List<Person> getMembers() {
-        return members;
-    }
-
-    public void setMembers(List<Person> members) {
-        this.members = members;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title  = title;
-    }
-
-    public Long getEntityId() {
-        return entityId;
-    }
-
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-
+    void setTitle(String title);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/OAuthConsumerStore.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/OAuthConsumerStore.java
new file mode 100644
index 0000000..68f6d48
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/OAuthConsumerStore.java
@@ -0,0 +1,57 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+

+import javax.xml.bind.annotation.XmlTransient;

+

+@XmlTransient

+public interface OAuthConsumerStore {

+    /**

+     * enum of KeyType's

+     */

+    public static enum KeyType {

+        HMAC_SYMMETRIC, RSA_PRIVATE, PLAINTEXT

+    }

+

+    Long getId();

+    void setId(Long id);

+

+    String getGadgetUri();

+    void setGadgetUri(String gadgetUri);

+

+    String getServiceName();

+    void setServiceName(String serviceName);

+

+    String getConsumerKey();

+    void setConsumerKey(String consumerKey);

+

+    String getConsumerSecret();

+    void setConsumerSecret(String consumerSecret);

+

+    OAuthConsumerStore.KeyType getKeyType();

+    void setKeyType(OAuthConsumerStore.KeyType keyType);

+

+    String getKeyName();

+    void setKeyName(String keyName);

+

+    String getCallbackUrl();

+    void setCallbackUrl(String callbackUrl);

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/OAuthTokenInfo.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/OAuthTokenInfo.java
new file mode 100644
index 0000000..8967af0
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/OAuthTokenInfo.java
@@ -0,0 +1,60 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+import javax.xml.bind.annotation.XmlTransient;

+

+@XmlTransient

+public interface OAuthTokenInfo {

+    /**

+     * @see {@link org.apache.shindig.social.core.oauth.OAuthSecurityToken#getModuleId()}

+     */

+    public static final String MODULE_ID = "NOT_USED";

+

+    Long getId();

+    void setId(Long id);

+

+    String getAccessToken();

+    void setAccessToken(String accessToken);

+

+    String getTokenSecret();

+    void setTokenSecret(String tokenSecret);

+

+    String getSessionHandle();

+    void setSessionHandle(String sessionHandle);

+

+    long getTokenExpireMillis();

+    void setTokenExpireMillis(long tokenExpireMillis);

+

+    String getAppUrl();

+    void setAppUrl(String appUrl);

+

+    String getModuleId();

+    void setModuleId(String moduleId);

+

+    String getServiceName();

+    void setServiceName(String serviceName);

+

+    String getTokenName();

+    void setTokenName(String tokenName);

+

+    String getUserId();

+    void setUserId(String userId);

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Organization.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Organization.java
index de9046d..fae520b 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Organization.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Organization.java
@@ -1,203 +1,53 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.*;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.Date;
 
 /**
  */
-@Entity
-@Table(name = "organization")
-public class Organization implements BasicEntity {
+@XmlTransient
+public interface Organization {
+    Address getAddress();
 
-    /**
-     * The internal object ID used for references to this object. Should be generated by the
-     * underlying storage mechanism
-     */
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "organizationIdGenerator")
-    @TableGenerator(name = "organizationIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "organization", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    void setAddress(Address address);
 
-    @OneToOne
-    private Address address;
+    String getDescription();
 
-    @Basic
-    @Column(name = "description", length = 255)
-    private String description;
+    void setDescription(String description);
 
-    @Basic
-    @Column(name = "endDate")
-    @Temporal(TemporalType.DATE)
-    private Date endDate;
+    Date getEndDate();
 
-    @Basic
-    @Column(name = "field", length = 255)
-    private String field;
+    void setEndDate(Date endDate);
 
-    @Basic
-    @Column(name = "name", length = 255)
-    private String name;
+    String getField();
 
-    @Basic
-    @Column(name = "start_date")
-    @Temporal(TemporalType.DATE)
-    private Date startDate;
+    void setField(String field);
 
-    @Basic
-    @Column(name = "sub_field", length = 255)
-    private String subField;
+    String getName();
 
-    @Basic
-    @Column(name = "title", length = 255)
-    private String title;
+    void setName(String name);
 
-    @Basic
-    @Column(name = "webpage", length = 255)
-    private String webpage;
+    Date getStartDate();
 
-    @Basic
-    @Column(name = "type", length = 255)
-    private String qualifier;
+    void setStartDate(Date startDate);
 
+    String getSubField();
 
-    @Basic
-    @Column(name = "primary_organization")
-    private Boolean primary;
+    void setSubField(String subField);
 
-    /**
-     */
-    public Long getEntityId() {
-        return entityId;
-    }
+    String getTitle();
 
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
+    void setTitle(String title);
 
-    public Address getAddress() {
-        return address;
-    }
+    String getWebpage();
 
-    public void setAddress(Address address) {
-        this.address = address;
-    }
+    void setWebpage(String webpage);
 
-    public String getDescription() {
-        return description;
-    }
+    String getQualifier();
 
-    public void setDescription(String description) {
-        this.description = description;
-    }
+    void setQualifier(String qualifier);
 
-    public Date getEndDate() {
-        return endDate;
-    }
+    Boolean getPrimary();
 
-    public void setEndDate(Date endDate) {
-        this.endDate = endDate;
-    }
-
-    public String getField() {
-        return field;
-    }
-
-    public void setField(String field) {
-        this.field = field;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Date getStartDate() {
-        return startDate;
-    }
-
-    public void setStartDate(Date startDate) {
-        this.startDate = startDate;
-    }
-
-    public String getSubField() {
-        return subField;
-    }
-
-    public void setSubField(String subField) {
-        this.subField = subField;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public String getWebpage() {
-        return webpage;
-    }
-
-    public void setWebpage(String webpage) {
-        this.webpage = webpage;
-    }
-
-    public String getQualifier() {
-        return qualifier;
-    }
-
-    public void setQualifier(String qualifier) {
-        this.qualifier = qualifier;
-    }
-
-    public Boolean getPrimary() {
-        return primary;
-    }
-
-    public void setPrimary(Boolean primary) {
-        this.primary = primary;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        Organization that = (Organization) o;
-
-        if (entityId != null ? !entityId.equals(that.entityId) : that.entityId != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return entityId != null ? entityId.hashCode() : 0;
-    }
+    void setPrimary(Boolean primary);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Page.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Page.java
index aec0d89..0eba2bb 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Page.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Page.java
@@ -18,273 +18,35 @@
  */

 package org.apache.rave.portal.model;

 

-import org.apache.rave.persistence.BasicEntity;

-import org.codehaus.jackson.annotate.JsonManagedReference;

-

-import javax.persistence.*;

-import javax.xml.bind.annotation.XmlAccessorType;

-import javax.xml.bind.annotation.XmlAccessType;

-import javax.xml.bind.annotation.XmlAttribute;

-import javax.xml.bind.annotation.XmlElement;

-import javax.xml.bind.annotation.XmlRootElement;

-

-import java.io.Serializable;

-import java.util.ArrayList;

-import java.util.Collections;

-import java.util.Comparator;

+import javax.xml.bind.annotation.XmlTransient;

 import java.util.List;

 

-/**

- * A page, which consists of regions, and which may be owned by a {@link User} (note the ownership will likely need to

- * become more flexible to enable things like group ownership in the future).

- *

- * TODO RAVE-231: not all database providers will be able to support deferrable constraints

- * so for the time being I'm commenting out the owner/render sequence since it

- * will get updated in batches and blow up

- * @UniqueConstraint(columnNames={"owner_id","render_sequence"}

- *

- */

-@Entity

-@XmlRootElement

-@XmlAccessorType(XmlAccessType.NONE)

-@Table(name="page", uniqueConstraints={@UniqueConstraint(columnNames={"owner_id","name","page_type"})})

-@NamedQueries({

-        @NamedQuery(name = Page.DELETE_BY_USER_ID_AND_PAGE_TYPE, query="DELETE FROM Page p WHERE p.owner.entityId = :userId and p.pageType = :pageType"),

-        @NamedQuery(name = Page.USER_HAS_PERSON_PAGE, query="SELECT count(p) FROM Page p WHERE p.owner.entityId = :userId and p.pageType = :pageType")

-})

-@Access(AccessType.FIELD)

-public class Page implements BasicEntity, Serializable {

-    private static final long serialVersionUID = 1L;

+@XmlTransient

+public interface Page {

+    Long getId();

+    void setId(Long id);

 

-    public static final String DELETE_BY_USER_ID_AND_PAGE_TYPE = "Page.deleteByUserIdAndPageType";

-    public static final String USER_HAS_PERSON_PAGE = "Page.hasPersonPage";

+    String getName();

+    void setName(String name);

 

-    @XmlAttribute(name="id")

-    @Id @Column(name="entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageIdGenerator")

-    @TableGenerator(name = "pageIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "page", allocationSize = 1, initialValue = 1)

-    private Long entityId;

+    User getOwner();

+    void setOwner(User owner);

 

-    @XmlElement

-    @Basic(optional=false) @Column(name="name")

-    private String name;

+    PageLayout getPageLayout();

+    void setPageLayout(PageLayout pageLayout);

 

-    @ManyToOne

-    @JoinColumn(name = "owner_id")

-    private User owner;

+    List<Region> getRegions();

+    void setRegions(List<Region> regions);

 

-    @OneToOne(cascade=CascadeType.ALL)

-    @JoinColumn(name="parent_page_id")

-    private Page parentPage;

+    PageType getPageType();

+    void setPageType(PageType pageType);

 

-    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy="parentPage")

-    private List<Page> subPages;

+    Page getParentPage();

+    void setParentPage(Page parentPage);

 

-    @ManyToOne

-    @JoinColumn(name="page_layout_id")

-    private PageLayout pageLayout;

+    List<Page> getSubPages();

+    void setSubPages(List<Page> subPages);

 

-    @XmlElement(name="region")

-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)

-    @OrderBy("renderOrder")

-    @JoinColumn(name="page_id")

-    private List<Region> regions;

-

-    @Basic

-    @Column(name = "page_type")

-    @Enumerated(EnumType.STRING)

-    private PageType pageType;

-

-    @OneToMany(targetEntity=PageUser.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="page", orphanRemoval=true)

-    private List<PageUser> members;

-

-    @JsonManagedReference

-    public List<PageUser> getMembers() {

-        return members;

-    }

-

-    /**

-     * @param members the members to set

-     */

-    public void setMembers(List<PageUser> members) {

-       this.members = members;

-    }

-

-    public Page() {

-    }

-

-    public Page(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    public Page(Long entityId, User owner) {

-        this.entityId = entityId;

-        this.owner = owner;

-    }

-

-    /**

-     * Gets the persistence unique identifier

-     *

-     * @return id The ID of persisted object; null if not persisted

-     */

-    @Override

-    public Long getEntityId() {

-        return entityId;

-    }

-

-    @Override

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    /**

-     * Gets the user defined name of the page

-     *

-     * @return Valid name

-     */

-    public String getName() {

-        return name;

-    }

-

-    public void setName(String name) {

-        this.name = name;

-    }

-

-    /**

-     * Gets the {@link User} that owns the page

-     *

-     * @return Valid {@link User}

-     */

-    public User getOwner() {

-        return owner;

-    }

-

-    public void setOwner(User owner) {

-        this.owner = owner;

-    }

-

-    /**

-     * Gets the {@link PageLayout}

-     *

-     * @return Valid {@link PageLayout}

-     */

-    public PageLayout getPageLayout() {

-        return pageLayout;

-    }

-

-    public void setPageLayout(PageLayout pageLayout) {

-        this.pageLayout = pageLayout;

-    }

-

-    /**

-     * Gets the widget containing {@link Region}s of the page

-     *

-     * @return Valid list of {@link Region}s

-     */

-    @JsonManagedReference

-    public List<Region> getRegions() {

-        return regions;

-    }

-

-    public void setRegions(List<Region> regions) {

-        this.regions = regions;

-    }

-

-    public PageType getPageType() {

-        return pageType;

-    }

-

-    public void setPageType(PageType pageType) {

-        this.pageType = pageType;

-    }

-

-    public Page getParentPage() {

-        return parentPage;

-    }

-

-    public void setParentPage(Page parentPage) {

-        this.parentPage = parentPage;

-    }

-

-    public List<Page> getSubPages() {

-        // we need to manually sort the sub pages due to limitations in JPA's OrderBy annotation dealing with

-        // sub-lists

-        List<Page> orderedSubPages = null;

-        if (this.subPages != null) {

-            orderedSubPages = new ArrayList<Page>(this.subPages);

-            Collections.sort(orderedSubPages, new SubPageComparator());

-        }

-        return orderedSubPages;

-    }

-

-    public void setSubPages(List<Page> subPages) {

-        this.subPages = subPages;

-    }

-

-    @Override

-    public boolean equals(Object obj) {

-        if (obj == null) {

-            return false;

-        }

-        if (getClass() != obj.getClass()) {

-            return false;

-        }

-        final Page other = (Page) obj;

-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {

-            return false;

-        }

-        return true;

-    }

-

-    @Override

-    public int hashCode() {

-        int hash = 7;

-        hash = 89 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);

-        return hash;

-    }

-

-    @Override

-    public String toString() {

-        return "Page{" + "entityId=" + entityId + ", name=" + name + ", owner=" + owner + ", pageLayout=" + pageLayout + ", pageType=" + pageType + "}";

-    }

-

-    /**

-     * Comparator used to sort sub pages.  It looks for PageUser objects representing the sub pages that are owned

-     * by the parent page user, and uses the renderSequence as the sorting field

-     */

-    class SubPageComparator implements Comparator<Page> {

-        @Override

-        public int compare(Page o1, Page o2) {

-            if (o1 == null || o1.getMembers() == null || o1.getMembers().isEmpty()) {

-                return 1;

-            }

-

-            if (o2 == null || o2.getMembers() == null || o2.getMembers().isEmpty()) {

-                return -1;

-            }

-

-            Long o1RenderSequence = null;

-            Long o2RenderSequence = null;

-

-            // find the PageUser object representing the sub page owned by the user

-            for (PageUser pageUser : o1.getMembers()) {

-                if (pageUser.getUser().equals(o1.getOwner())) {

-                    o1RenderSequence = pageUser.getRenderSequence();

-                    break;

-                }

-            }

-

-            // find the PageUser object representing the sub page owned by the user

-            for (PageUser pageUser : o2.getMembers()) {

-                if (pageUser.getUser().equals(o2.getOwner())) {

-                    o2RenderSequence = pageUser.getRenderSequence();

-                    break;

-                }

-            }

-

-            // compare the renderSequences of these two PageUser objects to determine the sort order

-            return o1RenderSequence.compareTo(o2RenderSequence);

-        }

-    }

+    List<PageUser> getMembers();

+    void setMembers(List<PageUser> members);

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageLayout.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageLayout.java
index d310c02..e89421a 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageLayout.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageLayout.java
@@ -1,157 +1,32 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
+import javax.xml.bind.annotation.XmlTransient;
 
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import java.io.Serializable;
-
-/**
- * Represents an organization of regions within a page that is supported by the rendering engine
- */
-@Entity
-@Table(name="page_layout")
-@NamedQueries({
-    @NamedQuery(name=PageLayout.PAGELAYOUT_GET_BY_LAYOUT_CODE, query = "select pl from PageLayout pl where pl.code = :code"),
-    @NamedQuery(name=PageLayout.PAGELAYOUT_GET_ALL, query="select pl from PageLayout pl order by pl.renderSequence"),
-    @NamedQuery(name=PageLayout.PAGELAYOUT_GET_ALL_USER_SELECTABLE, query="select pl from PageLayout pl where pl.userSelectable = true order by pl.renderSequence")
-})
-
-public class PageLayout implements BasicEntity, Serializable {
-    private static final long serialVersionUID = 1L;
-
-    // static string identifiers for JPA queries
-    public static final String PAGELAYOUT_GET_BY_LAYOUT_CODE = "PageLayout.getByLayoutCode";
-    public static final String PAGELAYOUT_GET_ALL = "PageLayout.getAll";
-    public static final String PAGELAYOUT_GET_ALL_USER_SELECTABLE = "PageLayout.getAllUserSelectable";
-    
-    @Id @Column(name="entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageLayoutIdGenerator")
-    @TableGenerator(name = "pageLayoutIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_layout", allocationSize = 1, initialValue = 1)
-    private Long entityId;
-
-    @Basic @Column(name="code", unique = true)
-    private String code;
-
-    @Basic @Column(name="number_of_regions")
-    private Long numberOfRegions;
-
-    @Basic(optional=false) @Column(name="render_sequence")
-    private Long renderSequence;
-
-    @Basic
-    @Column(name = "user_selectable")
-    private boolean userSelectable;
-
-    /**
-     * Gets the persistence unique identifier
-     *
-     * @return id The ID of persisted object; null if not persisted
-     */
-    @Override
-    public Long getEntityId() {
-        return entityId;
-    }
-
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-
+@XmlTransient
+public interface PageLayout {
     /**
      * Gets the code used by the rendering engine to identify the page layout
      *
      * @return Valid code known by rendering engine
      */
-    public String getCode() {
-        return code;
-    }
+    String getCode();
 
-    public void setCode(String code) {
-        this.code = code;
-    }
+    void setCode(String code);
 
     /**
      * Gets the number of regions supported by this page layout
      *
      * @return Valid number of regions > 0
      */
-    public Long getNumberOfRegions() {
-        return numberOfRegions;
-    }
+    Long getNumberOfRegions();
 
-    public void setNumberOfRegions(Long numberOfRegions) {
-        this.numberOfRegions = numberOfRegions;
-    }
+    void setNumberOfRegions(Long numberOfRegions);
 
-    public Long getRenderSequence() {
-        return renderSequence;
-    }
+    Long getRenderSequence();
 
-    public void setRenderSequence(Long renderSequence) {
-        this.renderSequence = renderSequence;
-    }
+    void setRenderSequence(Long renderSequence);
 
-    public boolean isUserSelectable() {
-        return userSelectable;
-    }
+    boolean isUserSelectable();
 
-    public void setUserSelectable(boolean userSelectable) {
-        this.userSelectable = userSelectable;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final PageLayout other = (PageLayout) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 5;
-        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        return "PageLayout{" + "entityId=" + entityId + ", code=" + code + ", numberOfRegions=" + numberOfRegions + '}';
-    }
-}
\ No newline at end of file
+    void setUserSelectable(boolean userSelectable);
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplate.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplate.java
index fd80649..9cf62c8 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplate.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplate.java
@@ -1,165 +1,46 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.model;

-

-import org.apache.rave.persistence.BasicEntity;

-

-import javax.persistence.*;

-import java.io.Serializable;

-import java.util.List;

-

-@Entity

-@Table(name="page_template")

-@NamedQueries({

-        @NamedQuery(name = PageTemplate.PAGE_TEMPLATE_GET_ALL, query = "SELECT p FROM PageTemplate p ORDER BY p.renderSequence"),

-        @NamedQuery(name = PageTemplate.PAGE_TEMPLATE_GET_DEFAULT_PAGE_BY_TYPE, query = "SELECT p FROM PageTemplate p WHERE p.defaultTemplate = true and p.pageType = :pageType")

-})

-@Access(AccessType.FIELD)

-public class PageTemplate implements BasicEntity, Serializable {

-

-    private static final long serialVersionUID = 1L;

-    public static final String PAGE_TEMPLATE_GET_ALL = "PageTemplate.getAll";

-    public static final String PAGE_TEMPLATE_GET_DEFAULT_PAGE_BY_TYPE = "PageTemplate.getDefaultPage";

-

-    @Id

-    @Column(name="entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageTemplateIdGenerator")

-    @TableGenerator(name = "pageTemplateIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_template", allocationSize = 1, initialValue = 1)

-    private Long entityId;

-

-    @Basic @Column(name="name", unique = false)

-    private String name;

-    

-    @Basic @Column(name="description", unique = false)

-    private String description;

-

-    @Basic(optional = false)

-    @Column(name="page_type", unique = false)

-    @Enumerated(EnumType.STRING)

-    private PageType pageType;

-

-    @OneToOne(cascade=CascadeType.ALL)

-    @JoinColumn(name="parent_page_template_id")

-    private PageTemplate parentPageTemplate;

-

-    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy="parentPageTemplate")

-    @OrderBy("renderSequence")

-    private List<PageTemplate> subPageTemplates;

-

-    @ManyToOne

-    @JoinColumn(name = "page_layout_id")

-    private PageLayout pageLayout;

-

-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)

-    @OrderBy("renderSequence")

-    @JoinColumn(name="page_template_id")

-    private List<PageTemplateRegion> pageTemplateRegions;

-

-    @Basic(optional = false)

-    @Column(name = "render_sequence")

-    private long renderSequence;

-

-    @Basic(optional = false)

-    @Column(name = "default_template")

-    private boolean defaultTemplate;

-

-    @Override

-    public Long getEntityId() {

-        return entityId;

-    }

-

-    @Override

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    public PageType getPageType() {

-        return pageType;

-    }

-

-    public void setPageType(PageType pageType) {

-        this.pageType = pageType;

-    }

-

-    public String getName() {

-        return name;

-    }

-

-    public void setName(String name) {

-        this.name = name;

-    }

-

-    public String getDescription() {

-        return description;

-    }

-

-    public void setDescription(String description) {

-        this.description = description;

-    }

-

-    public PageTemplate getParentPageTemplate() {

-        return parentPageTemplate;

-    }

-

-    public void setParentPageTemplate(PageTemplate parentPageTemplate) {

-        this.parentPageTemplate =  parentPageTemplate;

-    }

-

-    public PageLayout getPageLayout() {

-        return pageLayout;

-    }

-

-    public void setPageLayout(PageLayout pageLayout) {

-        this.pageLayout = pageLayout;

-    }

-

-    public List<PageTemplateRegion> getPageTemplateRegions() {

-        return pageTemplateRegions;

-    }

-

-    public void setPageTemplateRegions(List<PageTemplateRegion> pageTemplateRegions) {

-        this.pageTemplateRegions = pageTemplateRegions;

-    }

-

-    public long getRenderSequence() {

-        return renderSequence;

-    }

-

-    public void setRenderSequence(long renderSequence) {

-        this.renderSequence = renderSequence;

-    }

-

-    public boolean isDefaultTemplate() {

-        return defaultTemplate;

-    }

-

-    public void setDefaultTemplate(boolean defaultTemplate) {

-        this.defaultTemplate = defaultTemplate;

-    }

-

-    public List<PageTemplate> getSubPageTemplates() {

-        return subPageTemplates;

-    }

-

-    public void setSubPageTemplates(List<PageTemplate> subPageTemplates) {

-        this.subPageTemplates = subPageTemplates;

-    }    

-}

+package org.apache.rave.portal.model;
+
+import javax.xml.bind.annotation.XmlTransient;
+import java.util.List;
+
+@XmlTransient
+public interface PageTemplate {
+
+    Long getId();
+
+    PageType getPageType();
+
+    void setPageType(PageType pageType);
+
+    String getName();
+
+    void setName(String name);
+
+    String getDescription();
+
+    void setDescription(String description);
+
+    PageTemplate getParentPageTemplate();
+
+    void setParentPageTemplate(PageTemplate parentPageTemplate);
+
+    PageLayout getPageLayout();
+
+    void setPageLayout(PageLayout pageLayout);
+
+    List<PageTemplateRegion> getPageTemplateRegions();
+
+    void setPageTemplateRegions(List<PageTemplateRegion> pageTemplateRegions);
+
+    long getRenderSequence();
+
+    void setRenderSequence(long renderSequence);
+
+    boolean isDefaultTemplate();
+
+    void setDefaultTemplate(boolean defaultTemplate);
+
+    List<PageTemplate> getSubPageTemplates();
+
+    void setSubPageTemplates(List<PageTemplate> subPageTemplates);
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateRegion.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateRegion.java
index b1eeaa6..546f8a8 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateRegion.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateRegion.java
@@ -1,103 +1,29 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.model;

-

-import org.apache.rave.persistence.BasicEntity;

-

-import javax.persistence.*;

-import java.io.Serializable;

-import java.util.List;

-

-@Entity

-@Table(name = "page_template_region")

-@NamedQueries({

-        @NamedQuery(name = "PageTemplateRegion.findAll", query = "SELECT p FROM PageTemplateRegion p"),

-        @NamedQuery(name = "PageTemplateRegion.findByPageTemplateRegionId", query = "SELECT p FROM PageTemplateRegion p WHERE p.entityId = :id")

-})

-@Access(AccessType.FIELD)

-public class PageTemplateRegion implements BasicEntity, Serializable {

-    private static final long serialVersionUID = 1L;

-

-    @Id

-    @Column(name="entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageTemplateRegionIdGenerator")

-    @TableGenerator(name = "pageTemplateRegionIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_template_region", allocationSize = 1, initialValue = 1)

-    private Long entityId;

-

-    @Basic(optional = false)

-    @Column(name = "render_sequence")

-    private long renderSequence;

-

-    @JoinColumn(name = "page_template_id")

-    @ManyToOne(optional = false)

-    private PageTemplate pageTemplate;

-

-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)

-    @OrderBy("renderSequence")

-    @JoinColumn(name = "page_template_region_id")

-    private List<PageTemplateWidget> pageTemplateWidgets;

-    

-    @Basic(optional = false)

-    @Column(name = "locked")

-    private boolean locked;

-

-    @Override

-    public Long getEntityId() {

-        return entityId;

-    }

-

-    @Override

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    public long getRenderSequence() {

-        return renderSequence;

-    }

-

-    public void setRenderSequence(long renderSequence) {

-        this.renderSequence = renderSequence;

-    }

-

-    public PageTemplate getPageTemplate() {

-        return pageTemplate;

-    }

-

-    public void setPageTemplate(PageTemplate pageTemplate) {

-        this.pageTemplate = pageTemplate;

-    }

-

-    public List<PageTemplateWidget> getPageTemplateWidgets() {

-        return pageTemplateWidgets;

-    }

-

-    public void setPageTemplateWidgets(List<PageTemplateWidget> pageTemplateWidgets) {

-        this.pageTemplateWidgets = pageTemplateWidgets;

-    }

-

-    public boolean isLocked() {

-        return locked;

-    }

-

-    public void setLocked(boolean locked) {

-        this.locked = locked;

-    }

-}

+package org.apache.rave.portal.model;
+
+import javax.xml.bind.annotation.XmlTransient;
+import java.util.List;
+
+/**
+ */
+@XmlTransient
+public interface PageTemplateRegion {
+
+    Long getId();
+
+    long getRenderSequence();
+
+    void setRenderSequence(long renderSequence);
+
+    PageTemplate getPageTemplate();
+
+    void setPageTemplate(PageTemplate pageTemplate);
+
+    List<PageTemplateWidget> getPageTemplateWidgets();
+
+    void setPageTemplateWidgets(List<PageTemplateWidget> pageTemplateWidgets);
+
+    boolean isLocked();
+
+    void setLocked(boolean locked);
+
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateWidget.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateWidget.java
index ee0f558..f20f9c0 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateWidget.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageTemplateWidget.java
@@ -1,113 +1,31 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.model;

-

-import org.apache.rave.persistence.BasicEntity;

-

-import javax.persistence.*;

-import java.io.Serializable;

-

-@Entity

-@Table(name= "page_template_widget")

-@NamedQueries({

-        @NamedQuery(name = "PageTemplateGadget.findAll", query = "SELECT p FROM PageTemplateWidget p"),

-        @NamedQuery(name = "PageTemplateGadget.findByPageTemplateGadgetId", query = "SELECT p FROM PageTemplateWidget p WHERE p.entityId = :id")

-})

-@Access(AccessType.FIELD)

-public class PageTemplateWidget implements BasicEntity, Serializable {

-

-    private static final long serialVersionUID = 1L;

-

-    @Id

-    @Column(name="entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageTemplateWidgetIdGenerator")

-    @TableGenerator(name = "pageTemplateWidgetIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_template_widget", allocationSize = 1, initialValue = 1)

-    private Long entityId;

-

-    @JoinColumn(name = "page_template_region_id")

-    @ManyToOne(optional = false)

-    private PageTemplateRegion pageTemplateRegion;

-

-    @Basic(optional = false)

-    @Column(name = "render_sequence")

-    private long renderSequence;

-

-    @JoinColumn(name = "widget_id")

-    @ManyToOne(optional = false)

-    private Widget widget;

-

-    @Basic(optional = false)

-    @Column(name = "locked")

-    private boolean locked;

-

-    @Basic(optional = false)

-    @Column(name = "hide_chrome")

-    private boolean hideChrome;

-

-    @Override

-    public Long getEntityId() {

-        return entityId;

-    }

-

-    @Override

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    public PageTemplateRegion getPageTemplateRegion() {

-        return pageTemplateRegion;

-    }

-

-    public void setPageTemplateRegion(PageTemplateRegion pageTemplateRegion) {

-        this.pageTemplateRegion = pageTemplateRegion;

-    }

-

-    public long getRenderSeq() {

-        return renderSequence;

-    }

-

-    public void setRenderSeq(long renderSeq) {

-        this.renderSequence = renderSeq;

-    }

-

-    public Widget getWidget() {

-        return widget;

-    }

-

-    public void setWidget(Widget widget) {

-        this.widget = widget;

-    }

-

-    public boolean isLocked() {

-        return locked;

-    }

-

-    public void setLocked(boolean locked) {

-        this.locked = locked;

-    }

-

-    public boolean isHideChrome() {

-        return hideChrome;

-    }

-

-    public void setHideChrome(boolean hideChrome) {

-        this.hideChrome = hideChrome;

-    }

-}

+package org.apache.rave.portal.model;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+/**
+ */
+@XmlTransient
+public interface PageTemplateWidget {
+
+    Long getId();
+
+    PageTemplateRegion getPageTemplateRegion();
+
+    void setPageTemplateRegion(PageTemplateRegion pageTemplateRegion);
+
+    long getRenderSeq();
+
+    void setRenderSeq(long renderSeq);
+
+    Widget getWidget();
+
+    void setWidget(Widget widget);
+
+    boolean isLocked();
+
+    void setLocked(boolean locked);
+
+    boolean isHideChrome();
+
+    void setHideChrome(boolean hideChrome);
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageUser.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageUser.java
index b73a74d..6155d64 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageUser.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PageUser.java
@@ -18,156 +18,25 @@
  */

 package org.apache.rave.portal.model;

 

-import java.io.Serializable;

+import javax.xml.bind.annotation.XmlTransient;

 

-import javax.persistence.Basic;

-import javax.persistence.Column;

-import javax.persistence.Entity;

-import javax.persistence.EnumType;

-import javax.persistence.Enumerated;

-import javax.persistence.FetchType;

-import javax.persistence.GeneratedValue;

-import javax.persistence.GenerationType;

-import javax.persistence.Id;

-import javax.persistence.JoinColumn;

-import javax.persistence.ManyToOne;

-import javax.persistence.NamedQueries;

-import javax.persistence.NamedQuery;

-import javax.persistence.Table;

-import javax.persistence.TableGenerator;

-import javax.persistence.UniqueConstraint;

+@XmlTransient

+public interface PageUser {

+    Long getId();

+    void setId(Long id);

 

-import org.apache.rave.persistence.BasicEntity;

-import org.codehaus.jackson.annotate.JsonBackReference;

-@Entity

-@Table(name = "page_user", uniqueConstraints={@UniqueConstraint(columnNames={"page_id","user_id"})})

+    boolean isEditor();

+    void setEditor(boolean editor);

 

-@NamedQueries({

-        @NamedQuery(name = PageUser.GET_BY_USER_ID_AND_PAGE_TYPE, query="SELECT p.page FROM PageUser p, Page q WHERE p.page.entityId = q.entityId and p.user.entityId = :userId and q.pageType = :pageType ORDER BY p.renderSequence"),

-        @NamedQuery(name = PageUser.GET_PAGES_FOR_USER, query="SELECT p FROM PageUser p, Page q WHERE p.page.entityId = q.entityId and p.user.entityId = :userId and q.pageType = :pageType ORDER BY p.renderSequence"),

-        @NamedQuery(name = PageUser.GET_SINGLE_RECORD, query="SELECT p FROM PageUser p WHERE p.user.entityId = :userId and p.page.entityId = :pageId")

-})

-public class PageUser implements BasicEntity, Serializable {

-    private static final long serialVersionUID = 1L;

-    

-    public static final String GET_BY_USER_ID_AND_PAGE_TYPE ="PageUser.getByUserIdAndPageType";

-    public static final String GET_PAGES_FOR_USER = "PageUser.getPagesForUser";

-    public static final String GET_SINGLE_RECORD = "PageUser.getSingleRecord";

-    

-    @Id @Column(name="entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageUserIdGenerator")

-    @TableGenerator(name = "pageUserIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_user", allocationSize = 1, initialValue = 1)

-            

-    private Long entityId;

-    

-    @ManyToOne

-    @JoinColumn(name = "user_id")

-    private User user;

-    

-    @ManyToOne(fetch=FetchType.EAGER)

-    @JoinColumn(name = "page_id", nullable=false)

-    private Page page;

-    

-    @Basic(optional=false) @Column(name="editor")

-    private boolean editor;

-    

-    @Basic(optional=false) @Column(name="render_sequence")

-    private Long renderSequence;

-    

-    @Basic

-    @Column(name = "page_status")

-    @Enumerated(EnumType.STRING)

-    private PageInvitationStatus pageStatus;

-    

-    public Long getEntityId() {

-        return entityId;

-    }

+    User getUser();

+    void setUser(User user);

 

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-	

-    /**

-	 * @return the editor

-	 */

-	public boolean isEditor() {

-        return editor;

-	}

+    Page getPage();

+    void setPage(Page page);

 

-    /**

-    * @param editor the editor to set

-    */

-    public void setEditor(boolean editor) {

-        this.editor = editor;

-    }

+    Long getRenderSequence();

+    void setRenderSequence(Long renderSequence);

 

-    /**

-    * @return the user

-    */

-    public User getUser() {

-        return user;

-    }

-

-    /**

-    * @param user the user to set

-    */

-    public void setUser(User user) {

-        this.user = user;

-    }

-

-    /**

-    * @return the page

-    */

-    @JsonBackReference

-    public Page getPage() {

-        return page;

-    }

-

-    /**

-    * @param page the page to set

-    */

-    public void setPage(Page page) {

-        this.page = page;

-    }

-

-    /**

-     * Gets the order of the page instance relative to all pages for the owner (useful when presenting pages in an

-     * ordered layout like tabs or an accordion container)

-     *

-     * @return Valid, unique render sequence

-     */

-    public Long getRenderSequence() {

-        return renderSequence;

-    }

-

-    public void setRenderSequence(Long renderSequence) {

-        this.renderSequence = renderSequence;

-    }

-

-    /**

-     * Get the page status - used in shared states where a page can be pending, refused or accepted

-     * Only applies to shared pages

-     * @return an enum type

-     */

-    public PageInvitationStatus getPageStatus() {

-        return pageStatus;

-    }

-

-    public void setPageStatus(PageInvitationStatus pageStatus) {

-        this.pageStatus = pageStatus;

-    }

-    

-    public PageUser(){}

-    

-    public PageUser(User user, Page page){

-        this.user = user;

-        this.page = page;

-    }

-

-    public PageUser(User user, Page page, long sequence){

-        this.user = user;

-        this.page = page;

-        this.renderSequence = sequence;

-    }

+    PageInvitationStatus getPageStatus();

+    void setPageStatus(PageInvitationStatus pageStatus);

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Person.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Person.java
index 2bae727..605adea 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Person.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Person.java
@@ -1,274 +1,69 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.*;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.List;
 
 /**
- * Represents a person in the persistence context
  */
-@Entity
-@Table(name = "person")
-@NamedQueries(value = {
-    @NamedQuery(name = Person.FIND_BY_USERNAME, query = "select p from Person p where p.username like :username"),
-    @NamedQuery(name = Person.FIND_FRIENDS_BY_USERNAME, query = "select a.followed from PersonAssociation a where a.follower.username = :username"),
-    @NamedQuery(name = Person.FIND_BY_GROUP_MEMBERSHIP, query = "select m from Group g join g.members m where exists " +
-            "(select 'found' from g.members b where b.username = :username) and m.username <> :username")
-})
-public class Person implements BasicEntity {
+@XmlTransient
+public interface Person {
+    String getUsername();
 
-    public static final String FIND_BY_USERNAME = "Person.findByUsername";
-    public static final String FIND_FRIENDS_BY_USERNAME = "Person.findFriendsByUsername";
-    public static final String FIND_BY_GROUP_MEMBERSHIP = "Person.findByGroupMembership";
-    public static final String USERNAME_PARAM = "username";
+    void setUsername(String username);
 
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "personIdGenerator")
-    @TableGenerator(name = "personIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "person", allocationSize = 1, initialValue = 1)
-    protected Long entityId;
+    String getEmail();
 
-    @Basic
-    @Column(name = "username", unique = true)
-    protected String username;
+    void setEmail(String email);
 
-    @Basic
-    @Column(name = "email", unique = true)
-    protected String email;
+    String getDisplayName();
 
-    @Basic
-    @Column(name = "display_name", length = 255)
-    protected String displayName;
+    void setDisplayName(String displayName);
 
-    @Basic
-    @Column(name = "additional_name", length = 255)
-    protected String additionalName;
+    String getAboutMe();
 
-    @Basic
-    @Column(name = "family_name", length = 255)
-    protected String familyName;
+    void setAboutMe(String aboutMe);
 
-    @Basic
-    @Column(name = "given_name", length = 255)
-    protected String givenName;
+    String getPreferredName();
 
-    @Basic
-    @Column(name = "honorific_prefix", length = 255)
-    protected String honorificPrefix;
+    void setPreferredName(String preferredName);
 
-    @Basic
-    @Column(name = "honorific_suffix", length = 255)
-    protected String honorificSuffix;
+    String getStatus();
 
-    @Basic
-    @Column(name = "preferred_name")
-    protected String preferredName;
+    void setStatus(String status);
 
-    @Basic
-    @Column(name = "about_me")
-    protected String aboutMe;
+    String getAdditionalName();
 
-    @Basic
-    @Column(name = "status")
-    protected String status;
+    void setAdditionalName(String additionalName);
 
-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
-    @JoinTable(name = "person_address_jn",
-            joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "entity_id"),
-            inverseJoinColumns = @JoinColumn(name="person_id", referencedColumnName = "entity_id"))
-    protected List<Address> addresses;
+    String getFamilyName();
 
-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
-    @JoinColumn(name="person_id", referencedColumnName = "entity_id")
-    protected List<Organization> organizations;
+    void setFamilyName(String familyName);
 
-    @OneToMany(targetEntity = PersonProperty.class)
-    @JoinColumn(name = "person_id", referencedColumnName = "entity_id")
-    protected List<PersonProperty> properties;
+    String getGivenName();
 
-    @ManyToMany(fetch = FetchType.LAZY)
-    @JoinTable(name = "person_association",
-            joinColumns = @JoinColumn(name = "follower_id", referencedColumnName = "entity_id"),
-            inverseJoinColumns = @JoinColumn(name = "followed_id", referencedColumnName = "entity_id"))
-    protected List<Person> friends;
+    void setGivenName(String givenName);
 
-    @ManyToMany(fetch = FetchType.LAZY)
-    @JoinTable(name = "group_members",
-            joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "entity_id"),
-            inverseJoinColumns = @JoinColumn(name = "group_id", referencedColumnName = "entity_id"))
-    private List<Group> groups;
+    String getHonorificPrefix();
 
-    public Long getEntityId() {
-        return entityId;
-    }
+    void setHonorificPrefix(String honorificPrefix);
 
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
+    String getHonorificSuffix();
 
-    public String getUsername() {
-        return username;
-    }
+    void setHonorificSuffix(String honorificSuffix);
 
-    public void setUsername(String username) {
-        this.username = username;
-    }
+    List<Address> getAddresses();
 
-    public String getEmail() {
-        return email;
-    }
+    void setAddresses(List<Address> addresses);
 
-    public void setEmail(String email) {
-        this.email = email;
-    }
+    List<PersonProperty> getProperties();
 
-    public String getDisplayName() {
-        return displayName;
-    }
+    void setProperties(List<PersonProperty> properties);
 
-    public void setDisplayName(String displayName) {
-        this.displayName = displayName;
-    }
+    List<Person> getFriends();
 
-    public String getAboutMe() {
-        return aboutMe;
-    }
+    void setFriends(List<Person> friends);
 
-    public void setAboutMe(String aboutMe) {
-        this.aboutMe = aboutMe;
-    }
+    List<Organization> getOrganizations();
 
-    public String getPreferredName() {
-        return preferredName;
-    }
-
-    public void setPreferredName(String preferredName) {
-        this.preferredName = preferredName;
-    }
-
-    public String getStatus() {
-        return status;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    public String getAdditionalName() {
-        return additionalName;
-    }
-
-    public void setAdditionalName(String additionalName) {
-        this.additionalName = additionalName;
-    }
-
-    public String getFamilyName() {
-        return familyName;
-    }
-
-    public void setFamilyName(String familyName) {
-        this.familyName = familyName;
-    }
-
-    public String getGivenName() {
-        return givenName;
-    }
-
-    public void setGivenName(String givenName) {
-        this.givenName = givenName;
-    }
-
-    public String getHonorificPrefix() {
-        return honorificPrefix;
-    }
-
-    public void setHonorificPrefix(String honorificPrefix) {
-        this.honorificPrefix = honorificPrefix;
-    }
-
-    public String getHonorificSuffix() {
-        return honorificSuffix;
-    }
-
-    public void setHonorificSuffix(String honorificSuffix) {
-        this.honorificSuffix = honorificSuffix;
-    }
-
-    public List<Address> getAddresses() {
-        return addresses;
-    }
-
-    public void setAddresses(List<Address> addresses) {
-        this.addresses = addresses;
-    }
-
-    public List<PersonProperty> getProperties() {
-        return properties;
-    }
-
-    public void setProperties(List<PersonProperty> properties) {
-        this.properties = properties;
-    }
-
-    public List<Person> getFriends() {
-        return friends;
-    }
-
-    public void setFriends(List<Person> friends) {
-        this.friends = friends;
-    }
-
-    public List<Organization> getOrganizations() {
-        return organizations;
-    }
-
-    public void setOrganizations(List<Organization> organizations) {
-        this.organizations = organizations;
-    }
-
-    public List<Group> getGroups() {
-        return groups;
-    }
-
-    public void setGroups(List<Group> groups) {
-        this.groups = groups;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        Person person = (Person) o;
-
-        if (entityId != null ? !entityId.equals(person.entityId) : person.entityId != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return entityId != null ? entityId.hashCode() : 0;
-    }
+    void setOrganizations(List<Organization> organizations);
 }
-
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonProperty.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonProperty.java
index 066a7c2..ccd4a2b 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonProperty.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonProperty.java
@@ -1,151 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.*;
+import javax.xml.bind.annotation.XmlTransient;
 
 /**
- * A generic extension model for the {@link Person} that allows implementers to
- * add fields to the Person not initially envisioned
+ *
  */
-@Entity
-@Table(name = "person_property")
-public class PersonProperty implements BasicEntity {
+@XmlTransient
+public interface PersonProperty {
+    Long getId();
 
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "personPropertyIdGenerator")
-    @TableGenerator(name = "personPropertyIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "person_property", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    void setId(Long id);
 
-    /**
-     * The property type (IM, PhoneNumber, etc)
-     */
-    @Basic
-    @Column(name = "type")
-    private String type;
+    String getType();
 
-    /**
-     * The value of the field
-     */
-    @Basic
-    @Column(name = "value")
-    private String value;
+    void setType(String type);
 
-    /**
-     * The distinguishing qualifier (Home, Work, etc)
-     */
-    @Basic
-    @Column(name = "qualifier")
-    private String qualifier;
+    String getValue();
 
-    /**
-     * Extended information related to the value
-     */
-    @Basic
-    @Column(name = "extended_value")
-    private String extendedValue;
+    void setValue(String value);
 
-    /**
-     * Determines whether or not the property is the designated primary for the type
-     */
-    @Basic
-    @Column(name = "primary_value")
-    private Boolean primary;
+    String getQualifier();
 
-    public PersonProperty() {
-    }
+    void setQualifier(String qualifier);
 
-    public PersonProperty(Long entityId, String type, String value, String extendedValue, String qualifier, Boolean primary) {
-        this.entityId = entityId;
-        this.type = type;
-        this.value = value;
-        this.qualifier = qualifier;
-        this.primary = primary;
-        this.extendedValue = extendedValue;
-    }
+    Boolean getPrimary();
 
-    public Long getEntityId() {
-        return entityId;
-    }
+    void setPrimary(Boolean primary);
 
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
+    String getExtendedValue();
 
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-
-    public String getQualifier() {
-        return qualifier;
-    }
-
-    public void setQualifier(String qualifier) {
-        this.qualifier = qualifier;
-    }
-
-    public Boolean getPrimary() {
-        return primary;
-    }
-
-    public void setPrimary(Boolean primary) {
-        this.primary = primary;
-    }
-
-    public String getExtendedValue() {
-        return extendedValue;
-    }
-
-    public void setExtendedValue(String extendedValue) {
-        this.extendedValue = extendedValue;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        PersonProperty that = (PersonProperty) o;
-
-        if (entityId != null ? !entityId.equals(that.entityId) : that.entityId != null) return false;
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        return entityId != null ? entityId.hashCode() : 0;
-    }
-}
\ No newline at end of file
+    void setExtendedValue(String extendedValue);
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PortalPreference.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PortalPreference.java
index 9a6ff0a..4640f81 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PortalPreference.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PortalPreference.java
@@ -1,127 +1,27 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.exception.NotSupportedException;
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.ElementCollection;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.LinkedList;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.List;
 
-/**
- * Bean to manage portal preferences like title suffix, logo, number of items per page etc
- */
-@Entity
-@Table(name = "portal_preference")
-@NamedQueries({
-        @NamedQuery(name = PortalPreference.GET_ALL, query = "SELECT pp FROM PortalPreference pp"),
-        @NamedQuery(name = PortalPreference.GET_BY_KEY,
-                query = "SELECT pp FROM PortalPreference pp WHERE pp.key = :" + PortalPreference.PARAM_KEY)
-})
-public class PortalPreference implements BasicEntity, Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    public static final String GET_ALL = "PortalPreference.getAll";
-    public static final String GET_BY_KEY = "PortalPreference.getByKey";
-    public static final String PARAM_KEY = "key";
-
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "portalPreferenceIdGenerator")
-    @TableGenerator(name = "portalPreferenceIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "portal_preference", allocationSize = 1, initialValue = 1)
-    private Long entityId;
-
-    @Basic
-    @Column(name = "preference_key", unique = true)
-    private String key;
-
-    @ElementCollection(fetch = FetchType.EAGER)
-    private List<String> values = new LinkedList<String>();
-
-    public PortalPreference() {
-        super();
-    }
-
-    public PortalPreference(String key, String value) {
-        super();
-        this.key = key;
-        this.values.add(value);
-    }
-
-    public PortalPreference(String key, List<String> values) {
-        super();
-        this.key = key;
-        this.values = values;
-    }
-
-    @Override
-    public Long getEntityId() {
-        return this.entityId;
-    }
-
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-
+@XmlTransient
+public interface PortalPreference {
     /**
      * Gets the key of the preference, e.g. "availableFruit"
      *
      * @return name of the preference key
      */
-    public String getKey() {
-        return key;
-    }
+    String getKey();
 
-    public void setKey(String key) {
-        this.key = key;
-    }
+    void setKey(String key);
 
     /**
      * Gets a String array of the preference values, e.g. {"apple", "pear", "orange"}
      *
      * @return String array of the preference values
      */
-    public List<String> getValues() {
-        return values;
-    }
+    List<String> getValues();
 
-    public void setValues(List<String> values) {
-        this.values = values;
-    }
+    void setValues(List<String> values);
 
     /**
      * Helper method for the view layer to get a single value for a preference.
@@ -129,68 +29,14 @@
      * If there is 1 value, it returns that value.
      *
      * @return the single value of the preference or {@literal null} if not set
-     * @throws NotSupportedException if the preference has multiple values
+     * @throws org.apache.rave.exception.NotSupportedException if the preference has multiple values
      */
-    public String getValue() {
-        if (values.isEmpty()) {
-            return null;
-        } else if (values.size() == 1) {
-            return values.get(0);
-        }
-        throw new NotSupportedException("Cannot return single value for a List of size " + values.size());
-    }
+    String getValue();
 
     /**
      * Sets a single value for a preference. Will overwrite any exisiting value(s)
      *
      * @param value String value of the preference
      */
-    public void setValue(String value) {
-        List<String> values = new ArrayList<String>();
-        values.add(value);
-        this.values = values;
-    }
-
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final PortalPreference other = (PortalPreference) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuffer sb = new StringBuffer();
-        sb.append("PortalPreference");
-        sb.append("{entityId=").append(entityId);
-        sb.append(", key='").append(key).append('\'');
-        sb.append(", values={");
-        if (values != null) {
-            for (int i = 0; i < values.size(); i++) {
-                if (i > 0) {
-                    sb.append(',');
-                }
-                sb.append('\'').append(values.get(i)).append('\'');
-            }
-            sb.append('}');
-        }
-        sb.append('}');
-        return sb.toString();
-    }
+    void setValue(String value);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Region.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Region.java
index 19cdd88..04ab652 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Region.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Region.java
@@ -18,180 +18,28 @@
  */
 package org.apache.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-import org.codehaus.jackson.annotate.JsonBackReference;
-import org.codehaus.jackson.annotate.JsonManagedReference;
-
-import javax.persistence.Access;
-import javax.persistence.AccessType;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.OrderBy;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import java.io.Serializable;
-import java.util.ArrayList;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.List;
-import javax.persistence.Basic;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
 
-/**
- * A region of a page, which can contain widget instances {@link RegionWidget}
- */
-@XmlAccessorType(XmlAccessType.NONE)
-@Entity
-@Table(name="region")
-@Access(AccessType.FIELD)
-public class Region implements BasicEntity, Serializable {
-    private static final long serialVersionUID = 1L;
-     
-    @Id @Column(name="entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "regionIdGenerator")
-    @TableGenerator(name = "regionIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "region", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+@XmlTransient
+public interface Region {
+    Long getId();
 
-    @ManyToOne
-    @JoinColumn(name = "page_id")
-    private Page page;
+    void setId(Long id);
 
-    @Basic
-    @Column(name = "render_order")
-    private int renderOrder;
-    
-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
-    @OrderBy("renderOrder")
-    @JoinColumn(name = "region_id")
-    private List<RegionWidget> regionWidgets;
+    Page getPage();
 
-    @Basic(optional = false)
-    @Column(name = "locked")
-    private boolean locked;
+    void setPage(Page page);
 
-    public Region() {
-    }
+    int getRenderOrder();
 
-    public Region(Long entityId) {
-        this.entityId = entityId;
-    }
+    void setRenderOrder(int renderOrder);
 
-    public Region(Long entityId, Page page, int renderOrder) {
-        this.entityId = entityId;
-        this.page = page;
-        this.renderOrder = renderOrder;
-    }
-    
-    @SuppressWarnings("unused")
-    @XmlElement(name="widget")
-    /**
-     * Only used for XML serialization, omitting regionwidget
-     */
-    private List<Widget> getWidgets(){
-        ArrayList<Widget> widgets = new ArrayList<Widget>();
-        for (RegionWidget rw: regionWidgets){
-            widgets.add(rw.getWidget());
-        }
-        return widgets;
-    }
+    List<RegionWidget> getRegionWidgets();
 
-    /**
-     * Gets the persistence unique identifier
-     *
-     * @return id The ID of persisted object; null if not persisted
-     */
-    @Override
-    public Long getEntityId() {
-        return entityId;
-    }
+    void setRegionWidgets(List<RegionWidget> regionWidgets);
 
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
+    boolean isLocked();
 
-    /**
-     * Gets the associated page
-     *
-     * @return the associated page
-     */
-    @JsonBackReference
-    public Page getPage() {
-        return page;
-    }
-
-    public void setPage(Page page) {
-        this.page = page;
-    }
-    
-    /**
-     * Gets the order relative to regions on the page
-     * 
-     * @return the order of the region
-     */
-    public int getRenderOrder() {
-        return renderOrder;
-    }
-
-    public void setRenderOrder(int renderOrder) {
-        this.renderOrder = renderOrder;
-    }
-
-    /**
-     * Gets the ordered list of widget instances for the region
-     *
-     * @return Valid list
-     */
-    @JsonManagedReference
-    public List<RegionWidget> getRegionWidgets() {
-        return regionWidgets;
-    }
-
-    public void setRegionWidgets(List<RegionWidget> regionWidgets) {
-        this.regionWidgets = regionWidgets;
-    }
-
-    public boolean isLocked() {
-        return locked;
-    }
-
-    public void setLocked(boolean locked) {
-        this.locked = locked;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Region other = (Region) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 3;
-        hash = 67 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        return "Region{" + "entityId=" + entityId + ", pageId=" + ((page == null) ? null : page.getEntityId()) + ", regionWidgets=" + regionWidgets + '}';
-    }
+    void setLocked(boolean locked);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidget.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidget.java
index a12fba5..6528b24 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidget.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidget.java
@@ -16,240 +16,50 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
 import org.codehaus.jackson.annotate.JsonBackReference;
 
-import javax.persistence.*;
-import java.io.Serializable;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.List;
 
-/**
- * A widget within a region
- */
-@Entity
-@Table(name = "region_widget")
-@NamedQueries({
-        @NamedQuery(name = RegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_ALL_WIDGETS,
-                    query = "select rw.widget.entityId, count(distinct rw.region.page.owner) from RegionWidget rw group by rw.widget.entityId"),
-        @NamedQuery(name = RegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_SINGLE_WIDGET,
-                    query = "select count(distinct rw.region.page.owner) from RegionWidget rw where rw.widget.entityId = :widgetId")
-})
-public class RegionWidget implements BasicEntity, Serializable {
-    private static final long serialVersionUID = 1L;
+@XmlTransient
+public interface RegionWidget {
+    Long getId();
 
-    public static final String REGION_WIDGET_GET_DISTINCT_USER_COUNT_ALL_WIDGETS = "RegionWidget.getDistinctUserCountForAllWidgets";
-    public static final String REGION_WIDGET_GET_DISTINCT_USER_COUNT_SINGLE_WIDGET = "RegionWidget.getDistinctUserCount";
+    void setId(Long id);
 
-    public static final String PARAM_WIDGET_ID = "widgetId";
+    Widget getWidget();
 
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "regionWidgetIdGenerator")
-    @TableGenerator(name = "regionWidgetIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "region_widget", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    void setWidget(Widget widget);
 
-    @ManyToOne
-    @JoinColumn(name = "widget_id")
-    private Widget widget;
-
-    @ManyToOne
-    @JoinColumn(name = "region_id")
-    private Region region;
-
-    @Basic
-    @Column(name = "render_position")
-    private String renderPosition;
-
-    @Basic
-    @Column(name = "render_order")
-    private int renderOrder;
-
-    @Basic
-    @Column(name = "collapsed")
-    private boolean collapsed;
-
-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
-    @JoinColumn(name = "region_widget_id", referencedColumnName = "entity_id")
-    private List<RegionWidgetPreference> preferences;
-
-    @Basic(optional = false)
-    @Column(name = "locked")
-    private boolean locked;
-
-    @Basic(optional = false)
-    @Column(name = "hide_chrome")
-    private boolean hideChrome;
-
-    public RegionWidget() {
-    }
-
-    public RegionWidget(Long entityId) {
-        this.entityId = entityId;
-    }
-
-    public RegionWidget(Long entityId, Widget widget, Region region, int renderOrder) {
-        this.entityId = entityId;
-        this.widget = widget;
-        this.region = region;
-        this.renderOrder = renderOrder;
-    }
-
-    public RegionWidget(Long entityId, Widget widget, Region region) {
-        this.entityId = entityId;
-        this.widget = widget;
-        this.region = region;
-    }
-
-    /**
-     * Gets the persistence unique identifier
-     *
-     * @return id The ID of persisted object; null if not persisted
-     */
-    @Override
-    public Long getEntityId() {
-        return entityId;
-    }
-
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-
-    /**
-     * Gets the object that represents the metadata about the widget
-     *
-     * @return valid widget
-     */
-    public Widget getWidget() {
-        return widget;
-    }
-
-    public void setWidget(Widget widget) {
-        this.widget = widget;
-    }
-
-    /**
-     * Gets the associated region
-     *
-     * @return the region
-     */
     @JsonBackReference
-    public Region getRegion() {
-        return region;
-    }
+    Region getRegion();
 
-    public void setRegion(Region region) {
-        this.region = region;
-    }
+    void setRegion(Region region);
 
-    /**
-     * Gets the render position of this widget.  When the widget instance is being displayed on a "desktop" type view
-     * (single region where the user can drag and drop widgets to a particular X and Y coordinate within that region)
-     * this value might be an X and Y coordinate of the upper left hand corner of the widget.  It will be up to the
-     * rendering engine (based on the type of PageLayout associated with the Page this widget is rendering on) to
-     * determine how to use the value from this field.
-     *
-     * @return The RegionWidgets position within the Region
-     */
-    public String getRenderPosition() {
-        return renderPosition;
-    }
+    String getRenderPosition();
 
-    public void setRenderPosition(String renderPosition) {
-        this.renderPosition = renderPosition;
-    }
+    void setRenderPosition(String renderPosition);
 
-    /**
-     * Gets the order relative to other gadgets in the region
-     *
-     * @return the order of the gadget
-     */
-    public int getRenderOrder() {
-        return renderOrder;
-    }
+    int getRenderOrder();
 
-    public void setRenderOrder(int renderOrder) {
-        this.renderOrder = renderOrder;
-    }
+    void setRenderOrder(int renderOrder);
 
-    /**
-     * Gets whether or not to render the gadget in collapsed mode
-     *
-     * @return true if render collapsed; false otherwise
-     */
-    public boolean isCollapsed() {
-        return collapsed;
-    }
+    boolean isCollapsed();
 
-    public void setCollapsed(boolean collapsed) {
-        this.collapsed = collapsed;
-    }
+    void setCollapsed(boolean collapsed);
 
-    /**
-     * Gets the collection of user defined preferences for this RegionWidget.
-     *
-     * @return The user defined preferences for this RegionWidget.
-     */
-    public List<RegionWidgetPreference> getPreferences() {
-        return preferences;
-    }
+    List<RegionWidgetPreference> getPreferences();
 
-    public void setPreferences(List<RegionWidgetPreference> preferences) {
-        this.preferences = preferences;
-    }
+    void setPreferences(List<RegionWidgetPreference> preferences);
 
-    public boolean isLocked() {
-        return locked;
-    }
+    boolean isLocked();
 
-    public void setLocked(boolean locked) {
-        this.locked = locked;
-    }
+    void setLocked(boolean locked);
 
-    public boolean isHideChrome() {
-        return hideChrome;
-    }
+    boolean isHideChrome();
 
-    public void setHideChrome(boolean hideChrome) {
-        this.hideChrome = hideChrome;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final RegionWidget other = (RegionWidget) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 5;
-        hash = 23 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("RegionWidget{");
-        sb.append("entityId=");
-        sb.append(entityId);
-        sb.append(",widget=");
-        sb.append(widget);
-        sb.append(",regionId=");
-        sb.append(region.getEntityId());
-        sb.append("}");
-        return sb.toString();
-    }
-}
\ No newline at end of file
+    void setHideChrome(boolean hideChrome);
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidgetPreference.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidgetPreference.java
index 9a1737d..cabea5c 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidgetPreference.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/RegionWidgetPreference.java
@@ -1,156 +1,32 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.model;

-

-import org.apache.rave.persistence.BasicEntity;

-

-import javax.persistence.Basic;

-import javax.persistence.Column;

-import javax.persistence.Entity;

-import javax.persistence.GeneratedValue;

-import javax.persistence.GenerationType;

-import javax.persistence.Id;

-import javax.persistence.Table;

-import javax.persistence.TableGenerator;

-import javax.xml.bind.annotation.XmlRootElement;

-import java.io.Serializable;

-

-/**

- * A preference for a region widget.

- */

-@Entity

-@Table(name = "region_widget_preference")

-@XmlRootElement

-public class RegionWidgetPreference implements BasicEntity, Serializable {

-    private static final long serialVersionUID = 1L;

-    

-    @Id

-    @Column(name = "entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "regionWidgetPreferenceIdGenerator")

-    @TableGenerator(name = "regionWidgetPreferenceIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "region_widget_preference", allocationSize = 1, initialValue = 1)

-    private Long entityId;

-

-    @Basic

-    @Column(name = "region_widget_id")

-    private Long regionWidgetId;

-

-    @Basic

-    @Column(name = "name")

-    private String name;

-

-    @Basic

-    @Column(name = "value")

-    private String value;

-

-    public RegionWidgetPreference() {

-    }

-

-    public RegionWidgetPreference(Long entityId, Long regionWidgetId, String name, String value) {

-        this.entityId = entityId;

-        this.regionWidgetId = regionWidgetId;

-        this.name = name;

-        this.value = value;

-    }

-

-    /**

-     * Gets the persistence unique identifier

-     *

-     * @return id The ID of persisted object; null if not persisted

-     */

-    @Override

-    public Long getEntityId() {

-        return entityId;

-    }

-

-    @Override

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    /**

-     * Gets the ID of the RegionWidget this preference is for

-     * @return The ID of the RegionWidget this preference is for

-     */

-    public Long getRegionWidgetId() {

-        return regionWidgetId;

-    }

-

-    public void setRegionWidgetId(Long regionWidgetId) {

-        this.regionWidgetId = regionWidgetId;

-    }

-

-    /**

-     * Gets the name of the preference

-     *

-     * @return The name of the preference

-     */

-    public String getName() {

-        return name;

-    }

-

-    public void setName(String name) {

-        this.name = name;

-    }

-

-    /**

-     * Gets the value of this preference

-     *

-     * @return The value of this preference

-     */

-    public String getValue() {

-        return value;

-    }

-

-    public void setValue(String value) {

-        this.value = value;

-    }

-

-    @Override

-    public boolean equals(Object obj) {

-        if (obj == null) {

-            return false;

-        }

-        if (getClass() != obj.getClass()) {

-            return false;

-        }

-        final RegionWidgetPreference other = (RegionWidgetPreference) obj;

-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {

-            return false;

-        }

-        return true;

-    }

-

-    @Override

-    public int hashCode() {

-        int hash = 7;

-        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);

-        return hash;

-    }

-

-    @Override

-    public String toString() {

-        return "RegionWidgetPreference{" +

-                "entityId=" + entityId +

-                ", name='" + name + '\'' +

-                ", value='" + value + '\'' +

-                '}';

-    }

-}
\ No newline at end of file
+package org.apache.rave.portal.model;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+@XmlTransient
+public interface RegionWidgetPreference {
+    /**
+     * Gets the ID of the RegionWidget this preference is for
+     * @return The ID of the RegionWidget this preference is for
+     */
+    Long getRegionWidgetId();
+
+    void setRegionWidgetId(Long regionWidgetId);
+
+    /**
+     * Gets the name of the preference
+     *
+     * @return The name of the preference
+     */
+    String getName();
+
+    void setName(String name);
+
+    /**
+     * Gets the value of this preference
+     *
+     * @return The value of this preference
+     */
+    String getValue();
+
+    void setValue(String value);
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Tag.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Tag.java
index 1daf053..e90727b 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Tag.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Tag.java
@@ -1,126 +1,29 @@
 /*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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

+ * Copyright 2011 The Apache Software Foundation.

  *

- *   http://www.apache.org/licenses/LICENSE-2.0

+ * 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

  *

- * 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.

+ *      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.rave.portal.model;

 

-import org.apache.rave.persistence.BasicEntity;

-

-import javax.persistence.*;

-import java.util.ArrayList;

-import java.util.Collection;

+import javax.xml.bind.annotation.XmlTransient;

 import java.util.List;

 

-/**

- * Represents a group in the social database. The assumption in this object is that groups are

- * associated with individuals and are used by those individuals to manage people.

- */

-@Entity

-@Table(name = "tag")

-@NamedQueries({

-        @NamedQuery(name = Tag.GET_ALL, query = "select t from Tag t order by t.keyword asc"),

-        @NamedQuery(name = Tag.COUNT_ALL, query = "select count(t) from Tag t "),

-        @NamedQuery(name = Tag.GET_ALL_NOT_IN_WIDGET, query = "select tag from Tag tag where tag.keyword not in " +

-                        "(select t.keyword from Tag t join t.widgets w where w.widgetId =:widgetId)"),

+@XmlTransient

+public interface Tag {

 

-        @NamedQuery(name = Tag.FIND_BY_KEYWORD, query = "select t from Tag t where UPPER(t.keyword) = UPPER(:keyword)")

-})

+    String getKeyword();

+    void setKeyword(String keyword);

+    List<WidgetTag> getWidgets();

+    void setWidgets(List<WidgetTag> widgets);

 

-public class Tag implements BasicEntity {

-

-    public static final String FIND_BY_KEYWORD = "findByKeyword";

-    public static final String GET_ALL = "getAll";

-    public static final String COUNT_ALL = "countAll";

-    public static final String GET_ALL_NOT_IN_WIDGET="getAllNotInWidget" ;

-

-    /**

-     * The internal object ID used for references to this object. Should be generated by the

-     * underlying storage mechanism

-     */

-    @Id

-    @Column(name = "entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tagIdGenerator")

-    @TableGenerator(name = "tagIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "tag", allocationSize = 1, initialValue = 1)

-    private Long entityId;

-

-    @Basic

-    @Column(name = "keyword", unique = true)

-    private String keyword;

-

-    @OneToMany(mappedBy="tag")

-    public List<WidgetTag> widgets;

-

-

-    public Tag() {

-

-    }

-

-    public Tag(Long entityId, String keyword) {

-        this.entityId = entityId;

-        this.keyword = keyword;

-    }

-

-    public String getKeyword() {

-        return keyword;

-    }

-

-    public void setKeyword(String keyword) {

-        this.keyword = keyword;

-    }

-

-    public Long getEntityId() {

-        return entityId;

-    }

-

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    public List<WidgetTag> getWidgets() {

-        if (widgets==null) widgets=new ArrayList<WidgetTag>();

-        return widgets;

-    }

-

-    public void setWidgets(List<WidgetTag> widgets) {

-        this.widgets = widgets;

-    }

-

-    @Override

-    public boolean equals(Object o) {

-        if (this == o) {

-            return true;

-        }

-

-        if (o == null || getClass() != o.getClass()) {

-            return false;

-        }

-

-        Tag tag = (Tag) o;

-

-        if (entityId != null ? !entityId.equals(tag.entityId) : tag.entityId != null) {

-            return false;

-        }

-

-        return true;

-    }

-

-    @Override

-    public int hashCode() {

-        return entityId != null ? entityId.hashCode() : 0;

-    }

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java
index 9647f92..fb9f5fc 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/User.java
@@ -1,177 +1,22 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
 
-import javax.persistence.*;
-import java.io.Serializable;
-import java.util.*;
+import javax.xml.bind.annotation.XmlTransient;
+import java.util.Collection;
+import java.util.Date;
 
-/**
- * {@inheritDoc}
- * <p/>
- * A user of the system
- */
-@Entity
-@NamedQueries({
-        @NamedQuery(name = User.USER_GET_BY_USERNAME, query = "select u from User u where u.username = :"+User.PARAM_USERNAME),
-        @NamedQuery(name = User.USER_GET_BY_USER_EMAIL, query = "select u from User u where u.email = :"+User.PARAM_EMAIL),
-        @NamedQuery(name = User.USER_GET_ALL, query = "select u from User u order by u.username asc"),
-        @NamedQuery(name = User.USER_GET_BY_FORGOT_PASSWORD_HASH, query = "select u from User u where u.forgotPasswordHash = :" + User.PARAM_FORGOT_PASSWORD_HASH),
-        @NamedQuery(name = User.USER_COUNT_ALL, query = "select count(u) from User u"),
-        @NamedQuery(name = User.USER_FIND_BY_USERNAME_OR_EMAIL, query = "select u from User u " +
-                "where lower(u.username) like :"+User.PARAM_SEARCHTERM+" or lower(u.email) like :"+User.PARAM_SEARCHTERM+" order by u.username asc"),
-        @NamedQuery(name = User.USER_COUNT_FIND_BY_USERNAME_OR_EMAIL, query = "select count(u) from User u " +
-                "where lower(u.username) like :"+User.PARAM_SEARCHTERM+" or lower(u.email) like :"+User.PARAM_SEARCHTERM),
-        @NamedQuery(name = User.USER_GET_ALL_FOR_ADDED_WIDGET, query = "select distinct(rw.region.page.owner) from RegionWidget rw where rw.widget.entityId = :widgetId order by rw.region.page.owner.familyName, rw.region.page.owner.givenName")
-})
-public class User extends Person implements UserDetails, BasicEntity, Serializable {
-    private static final long serialVersionUID = 1L;
-
-    public static final String USER_GET_BY_USERNAME = "User.getByUsername";
-    public static final String USER_GET_BY_USER_EMAIL = "User.getByUserEmail";
-    public static final String USER_GET_ALL = "User.getAll";
-    public static final String USER_COUNT_ALL = "User.countAll";
-    public static final String USER_FIND_BY_USERNAME_OR_EMAIL = "User.findByUsernameOrEmail";
-    public static final String USER_COUNT_FIND_BY_USERNAME_OR_EMAIL = "User.countFindByUsernameOrEmail";
-    public static final String USER_GET_COMMENTERS = "User.getCommenters";
-    public static final String USER_GET_ALL_FOR_ADDED_WIDGET = "User.getAllForAddedWidget";
-    public static final String USER_GET_BY_FORGOT_PASSWORD_HASH = "User.getByForgotPasswordHash";
-
-    public static final String PARAM_USERNAME = "username";
-    public static final String PARAM_FORGOT_PASSWORD_HASH = "forgotPasswordHash";
-    public static final String PARAM_EMAIL = "email";
-    public static final String PARAM_SEARCHTERM = "searchTerm";
-    public static final String PARAM_WIDGET_ID = "widgetId";
-
-
-    @Basic
-    @Column(name = "password")
-    private String password;
-
-    @Basic
-    @Column(name = "expired")
-    private boolean expired;
-
-    @Basic
-    @Column(name = "locked")
-    private boolean locked;
-
-    @Basic
-    @Column(name = "enabled")
-    private boolean enabled;
-
-    @Basic
-    @Column(name = "openid")
-    private String openId;
-
-    @Basic
-    @Column(name = "forgotPasswordHash", unique = true)
-    private String forgotPasswordHash;
-
-    @Basic
-    @Column(name = "password_hash_time")
-    @Temporal(TemporalType.TIMESTAMP)
-    private Date forgotPasswordTime;
-
-    @ManyToOne
-    @JoinColumn(name="default_page_layout_id")
-    private PageLayout defaultPageLayout;
-
-    @OneToMany(targetEntity=PageUser.class, fetch = FetchType.LAZY, mappedBy="user", orphanRemoval=true)
-    private List<PageUser> pageUsers;
-
-    @OneToMany(targetEntity=WidgetTag.class, fetch = FetchType.LAZY, mappedBy="user", orphanRemoval=true)
-    private List<WidgetTag> widgetTags;
-
-    @Transient
-    private String confirmPassword;
-
-    @Transient
-    private String defaultPageLayoutCode;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(name = "user_authorities",
-            joinColumns =
-            @JoinColumn(name = "user_id", referencedColumnName = "entity_id"),
-            inverseJoinColumns =
-            @JoinColumn(name = "authority_id", referencedColumnName = "entity_id"))
-    private Collection<Authority> authorities;
-
-    public User() {
-        this(null, null);
-    }
-
-    public User(Long entityId) {
-        this(entityId, null);
-    }
-
-    public User(Long entityId, String username) {
-        super();
-        this.entityId = entityId;
-        this.username = username;
-        this.authorities = new ArrayList<Authority>();
-    }
-
-    /**
-     * Gets the unique identifier for this user.
-     *
-     * @return The unique identifier for this user.
-     */
+@XmlTransient
+public interface User extends Person, UserDetails {
     @Override
-    public Long getEntityId() {
-        return entityId;
-    }
+    Collection<GrantedAuthority> getAuthorities();
 
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
+    void addAuthority(Authority authority);
 
-    @Override
-    public Collection<GrantedAuthority> getAuthorities() {
-        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
-        grantedAuthorities.addAll(authorities);
-        return grantedAuthorities;
-    }
+    void removeAuthority(Authority authority);
 
-    public void addAuthority(Authority authority) {
-        if (!authorities.contains(authority)) {
-            authorities.add(authority);
-        }
-        if (!authority.getUsers().contains(this)) {
-            authority.addUser(this);
-        }
-    }
-
-    public void removeAuthority(Authority authority) {
-        if (authorities.contains(authority)) {
-            authorities.remove(authority);
-        }
-    }
-
-    public void setAuthorities(Collection<Authority> newAuthorities) {
-        this.authorities = newAuthorities;
-    }
+    void setAuthorities(Collection<Authority> newAuthorities);
 
     /**
      * Gets the password stored in the database
@@ -179,40 +24,24 @@
      * @return password as String
      */
     @Override
-    public String getPassword() {
-        return password;
-    }
+    String getPassword();
 
-    public void setPassword(String password) {
-        this.password = password;
-    }
+    void setPassword(String password);
 
     @Override
-    public String getUsername() {
-        return username;
-    }
+    String getUsername();
 
-    public void setUsername(String username) {
-        this.username = username;
-    }
+    void setUsername(String username);
 
     @Override
-    public boolean isAccountNonLocked() {
-        return !locked;
-    }
+    boolean isAccountNonLocked();
 
-    public boolean isLocked() {
-        return locked;
-    }
+    boolean isLocked();
 
-    public void setLocked(boolean locked) {
-        this.locked = locked;
-    }
+    void setLocked(boolean locked);
 
     @Override
-    public boolean isCredentialsNonExpired() {
-        return !expired;
-    }
+    boolean isCredentialsNonExpired();
 
     /**
      * Synchronized with password expiration {@see isCredentialsNonExpired}
@@ -221,158 +50,47 @@
      */
     //REVIEW NOTE: Conflating Account and Credential (non)expiration seems likely to cause confusion at some point.
     @Override
-    public boolean isAccountNonExpired() {
-        return isCredentialsNonExpired();
-    }
+    boolean isAccountNonExpired();
 
-    public boolean isExpired() {
-        return expired;
-    }
+    boolean isExpired();
 
-    public void setExpired(boolean expired) {
-        this.expired = expired;
-    }
+    void setExpired(boolean expired);
 
     @Override
-    public boolean isEnabled() {
-        return enabled;
-    }
+    boolean isEnabled();
 
-    public void setEnabled(boolean enabled) {
-        this.enabled = enabled;
-    }
+    void setEnabled(boolean enabled);
 
     //The following properties are specific to the user profile.
-    public String getEmail() {
-        return email;
-    }
+    String getEmail();
 
-    public void setEmail(String email) {
-        this.email = email;
-    }
+    void setEmail(String email);
 
-    public String getOpenId() {
-        return openId;
-    }
+    String getOpenId();
 
-    public void setOpenId(String openId) {
-        this.openId = openId;
-    }
+    void setOpenId(String openId);
 
-    public String getForgotPasswordHash() {
-        return forgotPasswordHash;
-    }
+    String getForgotPasswordHash();
 
-    public void setForgotPasswordHash(String forgotPasswordHash) {
-        this.forgotPasswordHash = forgotPasswordHash;
-    }
+    void setForgotPasswordHash(String forgotPasswordHash);
 
-    public Date getForgotPasswordTime() {
-        return forgotPasswordTime;
-    }
+    Date getForgotPasswordTime();
 
-    public void setForgotPasswordTime(Date forgotPasswordTime) {
-        this.forgotPasswordTime = forgotPasswordTime;
-    }
+    void setForgotPasswordTime(Date forgotPasswordTime);
 
-    public PageLayout getDefaultPageLayout() {
-        return defaultPageLayout;
-    }
+    PageLayout getDefaultPageLayout();
 
-    public void setDefaultPageLayout(PageLayout defaultPageLayout) {
-        this.defaultPageLayout = defaultPageLayout;
-    }
+    void setDefaultPageLayout(PageLayout defaultPageLayout);
 
     /**
 	 * @return the confirmPassword
 	 */
-	public String getConfirmPassword() {
-		return confirmPassword;
-	}
+    String getConfirmPassword();
 
-	/**
-	 * @param confirmPassword the confirmPassword to set
-	 */
-	public void setConfirmPassword(String confirmPassword) {
-		this.confirmPassword = confirmPassword;
-	}
-
-    public String getDefaultPageLayoutCode() {
-        return defaultPageLayoutCode;
-    }
-
-    public void setDefaultPageLayoutCode(String defaultPageLayoutCode) {
-        this.defaultPageLayoutCode = defaultPageLayoutCode;
-    }
-
-    public List<PageUser> getPageUsers() {
-        return pageUsers;
-    }
-
-    public void setPageUsers(List<PageUser> pageUsers) {
-        this.pageUsers = pageUsers;
-    }
-
-    public List<WidgetTag> getWidgetTags() {
-        return widgetTags;
-    }
-
-    public void setWidgetTags(List<WidgetTag> widgetTags) {
-        this.widgetTags = widgetTags;
-    }
-
-    @PreRemove
-    public void preRemove() {
-        for (Authority authority : authorities) {
-            authority.removeUser(this);
-        }
-        this.authorities = Collections.emptyList();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-
-        final User other = (User) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 67 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuffer sb = new StringBuffer();
-        sb.append("User");
-        sb.append("{entityId=").append(entityId);
-        sb.append(", username='").append(username).append('\'');
-        sb.append(", expired=").append(expired);
-        sb.append(", locked=").append(locked);
-        sb.append(", enabled=").append(enabled);
-        sb.append(", email='").append(email).append('\'');
-        sb.append(", openId='").append(openId).append('\'');
-        sb.append(", authorities=[");
-        boolean first=true;
-        for (Authority a : authorities) {
-            if (!first) {
-                sb.append(',');
-            }
-            sb.append('\'').append(a.getAuthority()).append('\'');
-            first = false;
-        }
-        sb.append(']');
-        sb.append('}');
-        return sb.toString();
-    }
+    /**
+     * @param confirmPassword the confirmPassword to set
+     */
+    void setConfirmPassword(String confirmPassword);
 
     /**
      * Conversion function to create a new Person object based off of this User class.  This is useful for when you
@@ -380,25 +98,11 @@
      *
      * @return a Person object representing the data contained in this class
      */
-    public Person toPerson() {
-        Person p = new Person();
-        p.setAboutMe(this.getAboutMe());
-        p.setAdditionalName(this.getAdditionalName());
-        p.setAddresses(this.getAddresses());
-        p.setDisplayName(this.getDisplayName());
-        p.setEmail(this.getEmail());
-        p.setEntityId(this.getEntityId());
-        p.setFamilyName(this.getFamilyName());
-        p.setFriends(this.getFriends());
-        p.setGivenName(this.getGivenName());
-        p.setHonorificPrefix(this.getHonorificPrefix());
-        p.setHonorificSuffix(this.getHonorificSuffix());
-        p.setOrganizations(this.getOrganizations());
-        p.setPreferredName(this.getPreferredName());
-        p.setProperties(this.getProperties());
-        p.setStatus(this.getStatus());
-        p.setUsername(this.getUsername());
-        return p;
-    }
+    Person toPerson();
 
+    Long getId();
+
+    String getDefaultPageLayoutCode();
+
+    void setDefaultPageLayoutCode(String pageLayoutCode);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Widget.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Widget.java
index a4e2d98..3300f8b 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Widget.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/Widget.java
@@ -1,419 +1,92 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.*;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import java.io.Serializable;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.List;
 
-/**
- * A widget
- */
-@XmlAccessorType(XmlAccessType.NONE)
-@Entity
-@Table(name = "widget")
-@NamedQueries({
-        @NamedQuery(name = Widget.WIDGET_GET_ALL, query = Widget.SELECT_W_FROM_WIDGET_W + Widget.ORDER_BY_TITLE_ASC),
-        @NamedQuery(name = Widget.WIDGET_COUNT_ALL, query = Widget.SELECT_COUNT_W_FROM_WIDGET_W),
+@XmlTransient
+public interface Widget {
+    Long getId();
 
-        @NamedQuery(name = Widget.WIDGET_GET_BY_OWNER,
-                query = Widget.SELECT_W_FROM_WIDGET_W + Widget.WHERE_CLAUSE_OWNER + Widget.ORDER_BY_TITLE_ASC),
-        @NamedQuery(name = Widget.WIDGET_COUNT_BY_OWNER,
-                query = Widget.SELECT_COUNT_W_FROM_WIDGET_W + Widget.WHERE_CLAUSE_OWNER),
+    String getScreenshotUrl();
 
-        @NamedQuery(name = Widget.WIDGET_GET_BY_FREE_TEXT,
-                query = Widget.SELECT_W_FROM_WIDGET_W + Widget.WHERE_CLAUSE_FREE_TEXT + Widget.ORDER_BY_TITLE_ASC),
-        @NamedQuery(name = Widget.WIDGET_COUNT_BY_FREE_TEXT,
-                query = Widget.SELECT_COUNT_W_FROM_WIDGET_W + Widget.WHERE_CLAUSE_FREE_TEXT),
+    void setScreenshotUrl(String screenshotUrl);
 
-        @NamedQuery(name = Widget.WIDGET_GET_BY_STATUS,
-                query = Widget.SELECT_W_FROM_WIDGET_W + Widget.WHERE_CLAUSE_STATUS + Widget.ORDER_BY_TITLE_ASC),
-        @NamedQuery(name = Widget.WIDGET_COUNT_BY_STATUS,
-                query = Widget.SELECT_COUNT_W_FROM_WIDGET_W + Widget.WHERE_CLAUSE_STATUS),
+    String getAuthor();
 
-        @NamedQuery(name = Widget.WIDGET_GET_BY_URL, query = Widget.SELECT_W_FROM_WIDGET_W + Widget.WHERE_CLAUSE_URL) ,
+    void setAuthor(String author);
 
-        @NamedQuery(name = Widget.WIDGET_GET_BY_TAG, query = Widget.SELECT_W_FROM_WIDGET_W + Widget.JOIN_TAGS+Widget.ORDER_BY_TITLE_ASC),
-        @NamedQuery(name = Widget.WIDGET_COUNT_BY_TAG, query = Widget.SELECT_COUNT_W_FROM_WIDGET_W + Widget.JOIN_TAGS),
-        @NamedQuery(name = Widget.WIDGET_UNASSIGN_OWNER, query = "UPDATE Widget w SET w.owner = null WHERE w.owner.entityId = :owner")
-})
-public class Widget implements BasicEntity, Serializable {
-    private static final long serialVersionUID = 1L;
+    String getAuthorEmail();
 
-    public static final String PARAM_SEARCH_TERM = "searchTerm";
-    public static final String PARAM_STATUS = "widgetStatus";
-    public static final String PARAM_URL = "url";
-    public static final String PARAM_OWNER = "owner";
-    public static final String PARAM_TAG = "keyword";
+    void setAuthorEmail(String authorEmail);
 
-    public static final String WIDGET_GET_ALL = "Widget.getAll";
-    public static final String WIDGET_COUNT_ALL = "Widget.countAll";
-    public static final String WIDGET_GET_BY_OWNER = "Widget.getByOwner";
-    public static final String WIDGET_COUNT_BY_OWNER = "Widget.countByOwner";
-    public static final String WIDGET_GET_BY_FREE_TEXT = "Widget.getByFreeText";
-    public static final String WIDGET_COUNT_BY_FREE_TEXT = "Widget.countByFreeText";
-    public static final String WIDGET_GET_BY_STATUS = "Widget.getByStatus";
-    public static final String WIDGET_COUNT_BY_STATUS = "Widget.countByStatus";
-    public static final String WIDGET_GET_BY_URL = "Widget.getByUrl";
-    public static final String WIDGET_GET_BY_TAG = "Widget.getByTag";
-    public static final String WIDGET_COUNT_BY_TAG = "Widget.countByTag";
-    public static final String WIDGET_UNASSIGN_OWNER = "Widget.unassignOwner";
+    String getDescription();
 
-    static final String SELECT_W_FROM_WIDGET_W = "SELECT w FROM Widget w ";
-    static final String SELECT_COUNT_W_FROM_WIDGET_W = "SELECT count(w) FROM Widget w ";
+    void setDescription(String description);
 
-    static final String WHERE_CLAUSE_FREE_TEXT =
-            " WHERE lower(w.title) LIKE :" + PARAM_SEARCH_TERM + " OR w.description LIKE :description";
-    static final String WHERE_CLAUSE_STATUS = " WHERE w.widgetStatus = :" + PARAM_STATUS;
-    static final String WHERE_CLAUSE_URL = " WHERE w.url = :" + PARAM_URL;
-    static final String WHERE_CLAUSE_OWNER = " WHERE w.owner = :" + PARAM_OWNER;
-    static final String WIDGET_TAG_BY_KEYWORD=" (select t.widgetId from WidgetTag t where lower(t.tag.keyword)=:"+PARAM_TAG+")";
-    static final String JOIN_TAGS=" WHERE w.entityId in"+WIDGET_TAG_BY_KEYWORD;
+    String getThumbnailUrl();
 
-    static final String ORDER_BY_TITLE_ASC = " ORDER BY w.featured DESC, w.title ASC ";
+    void setThumbnailUrl(String thumbnailUrl);
 
+    String getType();
 
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetIdGenerator")
-    @TableGenerator(name = "widgetIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    void setType(String type);
 
-    /*
-        TODO RAVE-234: Figure out what the OpenJPA strategy is for functionality provided by Eclisplink's @Convert
-     */
-    @XmlElement
-    @Basic
-    @Column(name = "title")
-    private String title;
-    //private InternationalString title;
+    String getTitle();
 
-    @XmlElement
-    @Basic
-    @Column(name = "title_url")
-    private String titleUrl;
+    void setTitle(String title);
 
-    @XmlElement
-    @Basic
-    @Column(name = "url", unique = true)
-    private String url;
+    String getTitleUrl();
 
-    @Basic
-    @Column(name = "thumbnail_url")
-    private String thumbnailUrl;
+    void setTitleUrl(String titleUrl);
 
-    @Basic
-    @Column(name = "screenshot_url")
-    private String screenshotUrl;
+    String getUrl();
 
-    @XmlElement
-    @Basic
-    @Column(name = "type")
-    private String type;
+    void setUrl(String url);
 
-    @XmlElement
-    @Basic
-    @Column(name = "author")
-    private String author;
+    WidgetStatus getWidgetStatus();
 
-    @XmlElement
-    @Basic
-    @Column(name = "author_email")
-    private String authorEmail;
+    void setWidgetStatus(WidgetStatus widgetStatus);
 
-    @XmlElement
-    @Basic
-    @Column(name = "description")
-    @Lob
-    private String description;
+    @XmlElementWrapper
+    List<WidgetComment> getComments();
 
-    @XmlElement(name = "status")
-    @Basic
-    @Column(name = "widget_status")
-    @Enumerated(EnumType.STRING)
-    private WidgetStatus widgetStatus;
+    void setComments(List<WidgetComment> comments);
 
-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
-    @JoinColumn(name = "widget_id", referencedColumnName = "entity_id")
-    private List<WidgetComment> comments;
+    User getOwner();
 
-    @ManyToOne
-    @JoinColumn(name = "owner_id")
-    private User owner;
-
-    @XmlElement
-    @Basic
-    @Column(name = "disable_rendering")
-    private boolean disableRendering;
-
-    @XmlElement
-    @Basic
-    @Column(name = "disable_rendering_message")
-    private String disableRenderingMessage;
-
-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
-    @JoinColumn(name = "widget_id", referencedColumnName = "entity_id")
-    private List<WidgetRating> ratings;
-
-    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
-    @JoinColumn(name = "widget_id", referencedColumnName = "entity_id")
-    private List<WidgetTag> tags;
-
-    @ManyToMany(fetch = FetchType.EAGER)
-    @JoinTable(name="widget_category",
-            joinColumns=@JoinColumn(name="widget_id", referencedColumnName = "entity_id"),
-            inverseJoinColumns=@JoinColumn(name="category_id", referencedColumnName = "entity_id")
-    )
-    @OrderBy("text")
-    private List<Category> categories;
-
-    @XmlElement
-    @Basic
-    @Column(name = "featured")
-    private boolean featured;
-
-    public Widget() {
-    }
-
-    public Widget(Long entityId, String url) {
-        this.entityId = entityId;
-        this.url = url;
-    }
-
-    /**
-     * Gets the persistence unique identifier
-     *
-     * @return id The ID of persisted object; null if not persisted
-     */
-    @Override
-    public Long getEntityId() {
-        return entityId;
-    }
-
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-
-    //See TODO RAVE-234
-//    public InternationalString getTitle() {
-//        return title;
-//    }
-//
-//    public void setTitle(InternationalString title) {
-//        this.title = title;
-//
-// }
-
-    public String getScreenshotUrl() {
-        return screenshotUrl;
-    }
-
-    public void setScreenshotUrl(String screenshotUrl) {
-        this.screenshotUrl = screenshotUrl;
-    }
-
-    public String getAuthor() {
-        return author;
-    }
-
-    public void setAuthor(String author) {
-        this.author = author;
-    }
-
-    public String getAuthorEmail() {
-        return authorEmail;
-    }
-
-    public void setAuthorEmail(String authorEmail) {
-        this.authorEmail = authorEmail;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getThumbnailUrl() {
-        return thumbnailUrl;
-    }
-
-    public void setThumbnailUrl(String thumbnailUrl) {
-        this.thumbnailUrl = thumbnailUrl;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    public String getTitleUrl() {
-        return titleUrl;
-    }
-
-    public void setTitleUrl(String titleUrl) {
-        this.titleUrl = titleUrl;
-    }
-
-    public String getUrl() {
-        return url;
-    }
-
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    public WidgetStatus getWidgetStatus() {
-        return widgetStatus;
-    }
-
-    public void setWidgetStatus(WidgetStatus widgetStatus) {
-        this.widgetStatus = widgetStatus;
-    }
-
-    public List<WidgetComment> getComments() {
-        return comments;
-    }
-
-    public void setComments(List<WidgetComment> comments) {
-        this.comments = comments;
-    }
-
-    public User getOwner() {
-        return owner;
-    }
-
-    public void setOwner(User owner) {
-        this.owner = owner;
-    }
+    void setOwner(User owner);
 
     /**
      * Gets the collection of user ratings for this Widget.
      *
      * @return The user ratings for this Widget.
      */
-    public List<WidgetRating> getRatings() {
-        return ratings;
-    }
+    @XmlElementWrapper
+    List<WidgetRating> getRatings();
 
-    public void setRatings(List<WidgetRating> ratings) {
-        this.ratings = ratings;
-    }
+    void setRatings(List<WidgetRating> ratings);
 
-    public boolean isDisableRendering() {
-        return disableRendering;
-    }
+    boolean isDisableRendering();
 
-    public void setDisableRendering(boolean disableRendering) {
-        this.disableRendering = disableRendering;
-    }
+    void setDisableRendering(boolean disableRendering);
 
-    public String getDisableRenderingMessage() {
-        return disableRenderingMessage;
-    }
+    String getDisableRenderingMessage();
 
-    public void setDisableRenderingMessage(String disableRenderingMessage) {
-        this.disableRenderingMessage = disableRenderingMessage;
-    }
+    void setDisableRenderingMessage(String disableRenderingMessage);
 
-    public List<WidgetTag> getTags() {
-        return tags;
-    }
+    @XmlElementWrapper
+    List<WidgetTag> getTags();
 
-    public void setTags(List<WidgetTag> tags) {
-        this.tags = tags;
-    }
+    void setTags(List<WidgetTag> tags);
 
-    public List<Category> getCategories() {
-        return categories;
-    }
+    @XmlElementWrapper
+    List<Category> getCategories();
 
-    public void setCategories(List<Category> categories) {
-        this.categories = categories;
-    }
+    void setCategories(List<Category> categories);
 
-    public boolean isFeatured() {
-        return featured;
-    }
+    boolean isFeatured();
 
-    public void setFeatured(boolean featured) {
-        this.featured = featured;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final Widget other = (Widget) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        return "Widget{" +
-                "entityId=" + entityId +
-                ", title='" + title + '\'' +
-                ", url='" + url + '\'' +
-                ", thumbnailUrl='" + thumbnailUrl + '\'' +
-                ", screenshotUrl='" + screenshotUrl + '\'' +
-                ", type='" + type + '\'' +
-                ", author='" + author + '\'' +
-                ", description='" + description + '\'' +
-                ", widgetStatus=" + widgetStatus + '\'' +
-                ", owner=" + owner + '\'' +
-                ", featured=" + featured + '\'' +
-                ", disable_rendering=" + disableRendering + '\'' +
-                ", disable_rendering_message=" + disableRenderingMessage +
-                '}';
-    }
+    void setFeatured(boolean featured);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetComment.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetComment.java
index 2d5df5d..095d96c 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetComment.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetComment.java
@@ -1,160 +1,47 @@
 /*
- * Copyright 2011 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
  *
- * 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
  *
- *      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.
+ * 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.*;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
+import javax.xml.bind.annotation.XmlTransient;
 import java.util.Date;
 
 /**
- * A comment for a widget.
+ * The a comment by a user for a widget
  */
-@Entity
-@Table(name = "widget_comment")
-@NamedQueries({
-        @NamedQuery(name = WidgetComment.DELETE_ALL_BY_USER,
-                query="DELETE FROM WidgetComment wc WHERE wc.user.entityId = :userId")
-})
-@XmlRootElement
-public class WidgetComment implements BasicEntity, Serializable {
-    public static final String DELETE_ALL_BY_USER = "WidgetComment.deleteAllByUserId";
+@XmlTransient
+public interface WidgetComment {
+    Long getId();
+    void setId(Long id);
 
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetCommentIdGenerator")
-    @TableGenerator(name = "widgetCommentIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget_comment", allocationSize = 1, initialValue = 1)
-    private Long entityId;
+    User getUser();
+    void setUser(User user);
 
-    @Basic
-    @Column(name = "widget_id")
-    private Long widgetId;
+    Long getWidgetId();
+    void setWidgetId(Long widgetId);
 
-    @ManyToOne(fetch=FetchType.EAGER)
-    @JoinColumn(name="user_id")
-    private User user;
+    String getText();
+    void setText(String text);
 
-    @Basic
-    @Column(name = "text") @Lob
-    private String text;
+    Date getLastModifiedDate();
+    void setLastModifiedDate(Date lastModified);
 
-    @Basic
-    @Column(name ="last_modified_date")
-    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
-    private Date lastModifiedDate;
-
-    @Basic
-    @Column(name ="created_date")
-    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
-    private Date createdDate;
-
-    public WidgetComment() {
-
-    }
-
-    public WidgetComment(Long entityId, Long widgetId, User user, String text, Date lastModified, Date created) {
-        this.entityId = entityId;
-        this.widgetId = widgetId;
-        this.user = user;
-        this.text = text;
-        this.lastModifiedDate = lastModified;
-        this.createdDate = created;
-    }
-
-    @Override
-    public Long getEntityId() {
-        return entityId;
-    }
-
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-
-    public Long getWidgetId() {
-        return widgetId;
-    }
-
-    public void setWidgetId(Long widgetId) {
-        this.widgetId = widgetId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    public String getText() {
-        return text;
-    }
-
-    public void setText(String text) {
-        this.text = text;
-    }
-
-    public Date getLastModifiedDate() {
-        return lastModifiedDate;
-    }
-
-    public void setLastModifiedDate(Date lastModified) {
-        this.lastModifiedDate = lastModified;
-    }
-
-    public Date getCreatedDate() {
-        return createdDate;
-    }
-
-    public void setCreatedDate(Date created) {
-        this.createdDate = created;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final WidgetComment other = (WidgetComment) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 79 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-
-    @Override
-    public String toString() {
-        return "WidgetComment{" +
-                "entityId=" + entityId +
-                ", widgetId=" + widgetId +
-                ", text='" + text + '\'' +
-                '}';
-    }
+    Date getCreatedDate();
+    void setCreatedDate(Date created);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetRating.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetRating.java
index 70c9fd9..de8fdb4 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetRating.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetRating.java
@@ -1,191 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.model;
 
-import org.apache.rave.persistence.BasicEntity;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-import javax.persistence.TableGenerator;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
+import javax.xml.bind.annotation.XmlTransient;
 
 /**
- * A Rating for a Widget
  */
-@Entity
-@Table(name = "widget_rating")
-@NamedQueries ({
-        @NamedQuery(name = WidgetRating.WIDGET_ALL_TOTAL_LIKES,
-                query = "SELECT COUNT(wr) total, wr.widgetId widgetIt FROM WidgetRating wr WHERE wr.score = 10 GROUP BY wr.widgetId"),
-        @NamedQuery(name = WidgetRating.WIDGET_TOTAL_LIKES,
-                query = "SELECT COUNT(wr) FROM WidgetRating wr WHERE wr.widgetId = :widgetId AND wr.score = 10"),
-        @NamedQuery(name = WidgetRating.WIDGET_ALL_TOTAL_DISLIKES,
-                query = "SELECT COUNT(wr) total, wr.widgetId widgetId FROM WidgetRating wr WHERE wr.score = 0 GROUP BY wr.widgetId"),
-        @NamedQuery(name = WidgetRating.WIDGET_TOTAL_DISLIKES,
-                query = "SELECT COUNT(wr) FROM WidgetRating wr WHERE wr.widgetId = :widgetId AND wr.score = 0"),
-        @NamedQuery(name = WidgetRating.WIDGET_ALL_USER_RATINGS,
-                query = "SELECT wr FROM WidgetRating wr WHERE wr.userId = :userId"),
-        @NamedQuery(name = WidgetRating.WIDGET_RATING_BY_WIDGET_AND_USER,
-                query = "SELECT wr FROM WidgetRating wr WHERE wr.widgetId = :widgetId AND wr.userId = :userId"),
-        @NamedQuery(name = WidgetRating.WIDGET_USER_RATING,
-                query = "SELECT wr.score FROM WidgetRating wr WHERE wr.widgetId = :widgetId AND wr.userId = :userId"),
-        @NamedQuery(name = WidgetRating.DELETE_ALL_BY_USER,
-                query="DELETE FROM WidgetRating wr WHERE wr.userId = :userId")
-})
-@XmlRootElement
-public class WidgetRating implements BasicEntity, Serializable {
-
-    public static final String WIDGET_ALL_TOTAL_LIKES = "widget_all_total_likes";
-    public static final String WIDGET_TOTAL_LIKES = "widget_total_likes";
-    public static final String WIDGET_ALL_TOTAL_DISLIKES = "widget_all_total_dislikes";
-    public static final String WIDGET_TOTAL_DISLIKES = "widget_total_dislikes";
-    public static final String WIDGET_ALL_USER_RATINGS = "widget_all_user_ratings";
-    public static final String WIDGET_RATING_BY_WIDGET_AND_USER = "widget_rating_by_widget_and_user";
-    public static final String WIDGET_USER_RATING = "widget_user_rating";
-    public static final String DELETE_ALL_BY_USER = "delete_all_for_user";
-
-    public static final String PARAM_WIDGET_ID = "widgetId";
-    public static final String PARAM_USER_ID = "userId";
-
-    @Id
-    @Column(name = "entity_id")
-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetRatingIdGenerator")
-    @TableGenerator(name = "widgetRatingIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
-            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget_rating", allocationSize = 1, initialValue = 1)
-    private Long entityId;
-    
-    @Basic
-    @Column(name = "widget_id")
-    private Long widgetId;
-    
-    @Basic
-    @Column(name = "user_id")
-    private Long userId;
-    
-    @Basic
-    @Column(name = "score")
-    private Integer score;
-    
-    public static final Integer LIKE = 10; 
-    public static final Integer DISLIKE = 0;
-    public static final Integer UNSET = -1;
-
-    public WidgetRating() {
-        
-    }
-    
-    public WidgetRating(Long entityId, Long widgetId, Long userId, Integer score) {
-        this.entityId = entityId;
-        this.widgetId = widgetId;
-        this.userId = userId;
-        this.score = score;
-    }
-    
-    /**
-     * Gets the persistence unique identifier
-     *
-     * @return id The ID of persisted object; null if not persisted
-     */
-    @Override
-    public Long getEntityId() {
-        return entityId;
-    }
-
-    @Override
-    public void setEntityId(Long entityId) {
-        this.entityId = entityId;
-    }
-    
+@XmlTransient
+public interface WidgetRating {
     /**
      * Gets the ID of the Widget this rating is for
      * @return The ID of the Widget this rating is for
      */
-    public Long getWidgetId() {
-        return widgetId;
-    }
+    Long getWidgetId();
 
-    public void setWidgetId(Long widgetId) {
-        this.widgetId = widgetId;
-    }
-    
+    void setWidgetId(Long widgetId);
+
     /**
      * Gets the ID of the User this rating is for
      * @return The ID of the User this rating is for
      */
-    public Long getUserId() {
-        return userId;
-    }
+    Long getUserId();
 
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-    
+    void setUserId(Long userId);
+
     /**
      * Gets the score of this rating
      *
      * @return The score of this rating
      */
-    public Integer getScore() {
-        return score;
-    }
+    Integer getScore();
 
-    public void setScore(Integer value) {
-        this.score = value;
-    }
-    
-    @Override
-    public int hashCode() {
-        int hash = 7;
-        hash = 59 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
-        return hash;
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final WidgetRating other = (WidgetRating) obj;
-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
-            return false;
-        }
-        return true;
-    }
-    
-    @Override
-    public String toString() {
-        return "WidgetRating{" +
-                "entityId=" + entityId +
-                ", widgetId=" + widgetId + 
-                ", userId=" + userId + 
-                ", score=" + score + 
-                '}';
-    }
+    void setScore(Integer value);
+
+    Long getId();
+
+    void setId(Long id);
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetTag.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetTag.java
index 7ec9d75..172aa32 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetTag.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/WidgetTag.java
@@ -13,137 +13,21 @@
  * See the License for the specific language governing permissions and

  * limitations under the License.

  */

+

 package org.apache.rave.portal.model;

 

-import org.apache.rave.persistence.BasicEntity;

-

-import javax.persistence.*;

-import javax.xml.bind.annotation.XmlRootElement;

-import java.io.Serializable;

+import javax.xml.bind.annotation.XmlTransient;

 import java.util.Date;

 

-/**

- * A tag for a widget.

- */

-@Entity

-@Table(name = "widget_tag")

-@XmlRootElement

-@NamedQueries({

-        @NamedQuery(name = WidgetTag.FIND_BY_WIDGET_AND_KEYWORD, query = "select t from WidgetTag t where t.widgetId=:widgetId and UPPER(t.tag.keyword) = UPPER(:keyword)")

-})

-

-public class WidgetTag implements BasicEntity, Serializable {

-

-    public static final String FIND_BY_WIDGET_AND_KEYWORD = "findByWidgetAndKeyword";

-

-    @Id

-    @Column(name = "entity_id")

-    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetTagIdGenerator")

-    @TableGenerator(name = "widgetTagIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

-            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget_tag", allocationSize = 1, initialValue = 1)

-    private Long entityId;

-

-    @Basic

-    @Column(name = "widget_id")

-    private Long widgetId;

-

-    @ManyToOne(fetch = FetchType.EAGER)

-    @JoinColumn(name = "user_id")

-    private User user;

-

-    @ManyToOne(fetch=FetchType.EAGER,cascade = CascadeType.ALL)

-    @JoinColumn(name = "tag_id")

-    private Tag tag;

-

-    @Basic

-    @Column(name = "created_date")

-    @Temporal(javax.persistence.TemporalType.TIMESTAMP)

-    private Date createdDate;

-

-    public WidgetTag() {

-

-    }

-

-    public WidgetTag(Long entityId, Long widgetId, User user, Date created, Tag tag) {

-        this.entityId = entityId;

-        this.widgetId = widgetId;

-        this.user = user;

-        this.tag = tag;

-        this.createdDate = created;

-    }

-

-    @Override

-    public Long getEntityId() {

-        return entityId;

-    }

-

-    @Override

-    public void setEntityId(Long entityId) {

-        this.entityId = entityId;

-    }

-

-    public Long getWidgetId() {

-        return widgetId;

-    }

-

-    public void setWidgetId(Long widgetId) {

-        this.widgetId = widgetId;

-    }

-

-    public User getUser() {

-        return user;

-    }

-

-    public void setUser(User user) {

-        this.user = user;

-    }

-

-

-

-    public Date getCreatedDate() {

-        return createdDate;

-    }

-

-    public void setCreatedDate(Date created) {

-        this.createdDate = created;

-    }

-

-    public Tag getTag() {

-        return tag;

-    }

-

-    public void setTag(Tag tag) {

-        this.tag = tag;

-    }

-

-    @Override

-    public boolean equals(Object obj) {

-        if (obj == null) {

-            return false;

-        }

-        if (getClass() != obj.getClass()) {

-            return false;

-        }

-        final WidgetTag other = (WidgetTag) obj;

-        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {

-            return false;

-        }

-        return true;

-    }

-

-    @Override

-    public int hashCode() {

-        int hash = 7;

-        hash = 79 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);

-        return hash;

-    }

-

-    @Override

-    public String toString() {

-        StringBuilder sb=new StringBuilder("WidgetTag") ;

-        sb.append("{").append("entityId=").append(entityId).append( ", widgetId=").append(widgetId);

-        if (tag!=null) sb.append("tag keyword=").append(tag.getKeyword());

-        sb.append("}") ;

-        return sb.toString();

-    }

+@XmlTransient

+public interface WidgetTag {

+    

+    Long getWidgetId();

+    void setWidgetId(Long id);

+    User getUser();

+    void setUser(User user);

+    Tag getTag();

+    void setTag(Tag tag);

+    Date getCreatedDate();

+    void setCreatedDate(Date date);

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/AddressImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/AddressImpl.java
new file mode 100644
index 0000000..d83035c
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/AddressImpl.java
@@ -0,0 +1,142 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.Address;
+
+/**
+ */
+public class AddressImpl implements Address {
+
+    private String country;
+    private Float latitude;
+    private Float longitude;
+    private String locality;
+    private String postalCode;
+    private String region;
+    private String streetAddress;
+    private String qualifier;
+    private String formatted;
+    private Boolean primary;
+
+    public AddressImpl() {  }
+
+    public AddressImpl(String street) {
+        this.streetAddress = street;
+    }
+
+    public String getCountry() {
+        return country;
+    }
+
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    public Float getLatitude() {
+        return latitude;
+    }
+
+    public void setLatitude(Float latitude) {
+        this.latitude = latitude;
+    }
+
+    public Float getLongitude() {
+        return longitude;
+    }
+
+    public void setLongitude(Float longitude) {
+        this.longitude = longitude;
+    }
+
+    public String getLocality() {
+        return locality;
+    }
+
+    public void setLocality(String locality) {
+        this.locality = locality;
+    }
+
+    public String getPostalCode() {
+        return postalCode;
+    }
+
+    public void setPostalCode(String postalCode) {
+        this.postalCode = postalCode;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    public String getStreetAddress() {
+        return streetAddress;
+    }
+
+    public void setStreetAddress(String streetAddress) {
+        this.streetAddress = streetAddress;
+    }
+
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    public void setQualifier(String qualifier) {
+        this.qualifier = qualifier;
+    }
+
+    public String getFormatted() {
+        return formatted;
+    }
+
+    public void setFormatted(String formatted) {
+        this.formatted = formatted;
+    }
+
+    public Boolean getPrimary() {
+        return primary;
+    }
+
+    public void setPrimary(Boolean primary) {
+        this.primary = primary;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof AddressImpl)) return false;
+
+        AddressImpl address = (AddressImpl) o;
+
+        if (country != null ? !country.equals(address.country) : address.country != null) return false;
+        if (formatted != null ? !formatted.equals(address.formatted) : address.formatted != null) return false;
+        if (latitude != null ? !latitude.equals(address.latitude) : address.latitude != null) return false;
+        if (locality != null ? !locality.equals(address.locality) : address.locality != null) return false;
+        if (longitude != null ? !longitude.equals(address.longitude) : address.longitude != null) return false;
+        if (postalCode != null ? !postalCode.equals(address.postalCode) : address.postalCode != null) return false;
+        if (primary != null ? !primary.equals(address.primary) : address.primary != null) return false;
+        if (qualifier != null ? !qualifier.equals(address.qualifier) : address.qualifier != null) return false;
+        if (region != null ? !region.equals(address.region) : address.region != null) return false;
+        if (streetAddress != null ? !streetAddress.equals(address.streetAddress) : address.streetAddress != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = country != null ? country.hashCode() : 0;
+        result = 31 * result + (latitude != null ? latitude.hashCode() : 0);
+        result = 31 * result + (longitude != null ? longitude.hashCode() : 0);
+        result = 31 * result + (locality != null ? locality.hashCode() : 0);
+        result = 31 * result + (postalCode != null ? postalCode.hashCode() : 0);
+        result = 31 * result + (region != null ? region.hashCode() : 0);
+        result = 31 * result + (streetAddress != null ? streetAddress.hashCode() : 0);
+        result = 31 * result + (qualifier != null ? qualifier.hashCode() : 0);
+        result = 31 * result + (formatted != null ? formatted.hashCode() : 0);
+        result = 31 * result + (primary != null ? primary.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/ApplicationDataImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/ApplicationDataImpl.java
new file mode 100644
index 0000000..6b59b84
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/ApplicationDataImpl.java
@@ -0,0 +1,79 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.impl;

+

+import org.apache.rave.portal.model.ApplicationData;

+

+import java.util.Map;

+

+public class ApplicationDataImpl implements ApplicationData {

+    private Long id;

+    private String userId;

+    private String appUrl;

+    private Map<String, String> data;

+

+    public ApplicationDataImpl() {}

+

+    public ApplicationDataImpl(Long id, String userId, String appUrl, Map<String, String> data) {

+        this.id = id;

+        this.userId = userId;

+        this.appUrl = appUrl;

+        this.data = data;

+    }

+

+    @Override

+    public Long getId() {

+        return id;

+    }

+

+    @Override

+    public void setId(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public String getUserId() {

+        return userId;

+    }

+

+    @Override

+    public void setUserId(String userId) {

+        this.userId = userId;

+    }

+

+    @Override

+    public String getAppUrl() {

+        return appUrl;

+    }

+

+    @Override

+    public void setAppUrl(String appUrl) {

+        this.appUrl = appUrl;

+    }

+

+    @Override

+    public Map<String, String> getData() {

+        return data;

+    }

+

+    @Override

+    public void setData(Map<String, String> data) {

+        this.data = data;

+    }

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/AuthorityImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/AuthorityImpl.java
new file mode 100644
index 0000000..8418bfd
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/AuthorityImpl.java
@@ -0,0 +1,85 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.User;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class AuthorityImpl implements Authority {
+
+    private String authority;
+    private Collection<User> users;
+    private boolean defaultForNewUser;
+
+    public AuthorityImpl(){
+        this.users = new ArrayList<User>();
+    }
+
+    public AuthorityImpl(String grantedAuthority) {
+        this();
+        this.authority = grantedAuthority;
+    }
+
+    public AuthorityImpl(GrantedAuthority grantedAuthority) {
+        this(grantedAuthority.getAuthority());
+    }
+
+    @Override
+    public String getAuthority() {
+        return authority;
+    }
+
+    @Override
+    public void setAuthority(String authority) {
+        this.authority = authority;
+    }
+
+    @Override
+    public Collection<User> getUsers() {
+        return users;
+    }
+
+    @Override
+    public void addUser(User user) {
+        this.users.add(user);
+    }
+
+    @Override
+    public void removeUser(User user) {
+        this.users.remove(user);
+    }
+
+    @Override
+    public boolean isDefaultForNewUser() {
+        return defaultForNewUser;
+    }
+
+    @Override
+    public void setDefaultForNewUser(boolean defaultForNewUser) {
+        this.defaultForNewUser = defaultForNewUser;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof AuthorityImpl)) return false;
+
+        AuthorityImpl authority1 = (AuthorityImpl) o;
+
+        if (defaultForNewUser != authority1.defaultForNewUser) return false;
+        if (authority != null ? !authority.equals(authority1.authority) : authority1.authority != null) return false;
+        if (users != null ? !users.equals(authority1.users) : authority1.users != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = authority != null ? authority.hashCode() : 0;
+        result = 31 * result + (users != null ? users.hashCode() : 0);
+        result = 31 * result + (defaultForNewUser ? 1 : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/CategoryImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/CategoryImpl.java
new file mode 100644
index 0000000..3a04338
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/CategoryImpl.java
@@ -0,0 +1,118 @@
+/*

+ * Copyright 2011 The Apache Software Foundation.

+ *

+ * 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.rave.portal.model.impl;

+

+import org.apache.rave.portal.model.*;

+

+import java.util.Date;

+import java.util.List;

+

+public class CategoryImpl implements Category {

+    private Long id;

+    private String text;

+    private User createdUser;

+    private Date createdDate;

+    private User lastModifiedUser;

+    private Date lastModifiedDate;

+    private List<Widget> widgets;

+

+    public CategoryImpl() {

+

+    }

+

+    public CategoryImpl(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public Long getId() {

+        return id;

+    }

+

+    @Override

+    public void setId(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public String getText() {

+        return text;

+    }

+

+    @Override

+    public void setText(String text) {

+        this.text = text;

+    }

+

+    @Override

+    public User getCreatedUser() {

+        return createdUser;

+    }

+

+    @Override

+    public void setCreatedUser(User createdUser) {

+        this.createdUser = createdUser;

+    }

+

+    @Override

+    public Date getCreatedDate() {

+        return createdDate;

+    }

+

+    @Override

+    public void setCreatedDate(Date createdDate) {

+        this.createdDate = createdDate;

+    }

+

+    @Override

+    public User getLastModifiedUser() {

+        return lastModifiedUser;

+    }

+

+    @Override

+    public void setLastModifiedUser(User lastModifiedUser) {

+        this.lastModifiedUser = lastModifiedUser;

+    }

+

+    @Override

+    public Date getLastModifiedDate() {

+        return lastModifiedDate;

+    }

+

+    @Override

+    public void setLastModifiedDate(Date lastModifiedDate) {

+        this.lastModifiedDate = lastModifiedDate;

+    }

+

+    @Override

+    public List<Widget> getWidgets() {

+        return widgets;

+    }

+

+    @Override

+    public void setWidgets(List<Widget> widgets) {

+        this.widgets = widgets;

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (this == obj) return true;

+        if (obj == null || getClass() != obj.getClass()) return false;

+        CategoryImpl category = (CategoryImpl) obj;

+        if (id != null ? !id.equals(category.getId()) : category.getId() != null) return false;

+        return true;

+    }

+ }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/GroupImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/GroupImpl.java
new file mode 100644
index 0000000..ffc9262
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/GroupImpl.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.*;
+
+import java.util.List;
+
+public class GroupImpl implements Group {
+
+    protected String description;
+    protected Person owner;
+    protected String title;
+    protected List<Person> members;
+
+    @Override
+    public Person getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(Person owner) {
+        this.owner = owner;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public List<Person> getMembers() {
+        return members;
+    }
+
+    @Override
+    public void setMembers(List<Person> members) {
+        this.members = members;
+    }
+
+    @Override
+    public String getTitle() {
+        return this.title;
+    }
+
+    @Override
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = description != null ? description.hashCode() : 0;
+        result = 31 * result + (owner != null ? owner.hashCode() : 0);
+        result = 31 * result + (title != null ? title.hashCode() : 0);
+        result = 31 * result + (members != null ? members.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof GroupImpl)) return false;
+
+        GroupImpl group = (GroupImpl) o;
+
+        if (description != null ? !description.equals(group.description) : group.description != null) return false;
+        if (owner != null ? !owner.equals(group.owner) : group.owner != null) return false;
+        if (members != null ? !members.equals(group.members) : group.members != null) return false;
+        if (title != null ? !title.equals(group.title) : group.title != null) return false;
+
+        return true;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OAuthConsumerStoreImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OAuthConsumerStoreImpl.java
new file mode 100644
index 0000000..7716724
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OAuthConsumerStoreImpl.java
@@ -0,0 +1,113 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.impl;

+

+import org.apache.rave.portal.model.OAuthConsumerStore;

+

+public class OAuthConsumerStoreImpl implements OAuthConsumerStore {

+    private Long id;

+    private String gadgetUri;

+    private String serviceName;

+    private String consumerKey;

+    private String consumerSecret;

+    private KeyType keyType;

+    private String keyName;

+    private String callbackUrl;

+

+    @Override

+    public Long getId() {

+        return id;

+    }

+

+    @Override

+    public void setId(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public String getGadgetUri() {

+        return gadgetUri;

+    }

+

+    @Override

+    public void setGadgetUri(String gadgetUri) {

+        this.gadgetUri = gadgetUri;

+    }

+

+    @Override

+    public String getServiceName() {

+        return serviceName;

+    }

+

+    @Override

+    public void setServiceName(String serviceName) {

+        this.serviceName = serviceName;

+    }

+

+    @Override

+    public String getConsumerKey() {

+        return consumerKey;

+    }

+

+    @Override

+    public void setConsumerKey(String consumerKey) {

+        this.consumerKey = consumerKey;

+    }

+

+    @Override

+    public String getConsumerSecret() {

+        return consumerSecret;

+    }

+

+    @Override

+    public void setConsumerSecret(String consumerSecret) {

+        this.consumerSecret = consumerSecret;

+    }

+

+    @Override

+    public KeyType getKeyType() {

+        return keyType;

+    }

+

+    @Override

+    public void setKeyType(KeyType keyType) {

+        this.keyType = keyType;

+    }

+

+    @Override

+    public String getKeyName() {

+        return keyName;

+    }

+

+    @Override

+    public void setKeyName(String keyName) {

+        this.keyName = keyName;

+    }

+

+    @Override

+    public String getCallbackUrl() {

+        return callbackUrl;

+    }

+

+    @Override

+    public void setCallbackUrl(String callbackUrl) {

+        this.callbackUrl = callbackUrl;

+    }

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OAuthTokenInfoImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OAuthTokenInfoImpl.java
new file mode 100644
index 0000000..edffff0
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OAuthTokenInfoImpl.java
@@ -0,0 +1,152 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.impl;

+

+import org.apache.rave.portal.model.OAuthTokenInfo;

+

+public class OAuthTokenInfoImpl implements OAuthTokenInfo {

+    private Long id;

+    private String accessToken;

+    private String tokenSecret;

+    private String sessionHandle;

+    private long tokenExpireMillis;

+    private String appUrl;

+    private String moduleId;

+    private String serviceName;

+    private String tokenName;

+    private String userId;

+

+    public OAuthTokenInfoImpl() {

+    }

+

+    public OAuthTokenInfoImpl(String appUrl, String serviceName,

+                              String tokenName, String accessToken, String sessionHandle,

+                              String tokenSecret, String userId, long tokenExpireMillis) {

+        this.setAccessToken(accessToken);

+        this.setAppUrl(appUrl);

+        this.setModuleId(MODULE_ID);

+        this.setServiceName(serviceName);

+        this.setSessionHandle(sessionHandle);

+        this.setTokenExpireMillis(tokenExpireMillis);

+        this.setTokenName(tokenName);

+        this.setTokenSecret(tokenSecret);

+        this.setUserId(userId);

+    }

+

+    @Override

+    public Long getId() {

+        return id;

+    }

+

+    @Override

+    public void setId(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public String getAccessToken() {

+        return accessToken;

+    }

+

+    @Override

+    public void setAccessToken(String accessToken) {

+        this.accessToken = accessToken;

+    }

+

+    @Override

+    public String getTokenSecret() {

+        return tokenSecret;

+    }

+

+    @Override

+    public void setTokenSecret(String tokenSecret) {

+        this.tokenSecret = tokenSecret;

+    }

+

+    @Override

+    public String getSessionHandle() {

+        return sessionHandle;

+    }

+

+    @Override

+    public void setSessionHandle(String sessionHandle) {

+        this.sessionHandle = sessionHandle;

+    }

+

+    @Override

+    public long getTokenExpireMillis() {

+        return tokenExpireMillis;

+    }

+

+    @Override

+    public void setTokenExpireMillis(long tokenExpireMillis) {

+        this.tokenExpireMillis = tokenExpireMillis;

+    }

+

+    @Override

+    public String getAppUrl() {

+        return appUrl;

+    }

+

+    @Override

+    public void setAppUrl(String appUrl) {

+        this.appUrl = appUrl;

+    }

+

+    @Override

+    public String getModuleId() {

+        return moduleId;

+    }

+

+    @Override

+    public void setModuleId(String moduleId) {

+        this.moduleId = moduleId;

+    }

+

+    @Override

+    public String getServiceName() {

+        return serviceName;

+    }

+

+    @Override

+    public void setServiceName(String serviceName) {

+        this.serviceName = serviceName;

+    }

+

+    @Override

+    public String getTokenName() {

+        return tokenName;

+    }

+

+    @Override

+    public void setTokenName(String tokenName) {

+        this.tokenName = tokenName;

+    }

+

+    @Override

+    public String getUserId() {

+        return userId;

+    }

+

+    @Override

+    public void setUserId(String userId) {

+        this.userId = userId;

+    }

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OrganizationImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OrganizationImpl.java
new file mode 100644
index 0000000..23d8f38
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/OrganizationImpl.java
@@ -0,0 +1,145 @@
+package org.apache.rave.portal.model.impl;
+import org.apache.rave.portal.model.Address;
+import org.apache.rave.portal.model.Organization;
+
+import java.util.Date;
+
+public class OrganizationImpl implements Organization {
+    private Address address;
+    private String description;
+    private Date endDate;
+    private String field;
+    private String name;
+    private Date startDate;
+    private String subField;
+    private String title;
+    private String webpage;
+    private String qualifier;
+    private Boolean primary;
+
+    public Address getAddress() {
+        return address;
+    }
+
+    public void setAddress(Address address) {
+        this.address = address;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    public String getField() {
+        return field;
+    }
+
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    public void setStartDate(Date startDate) {
+        this.startDate = startDate;
+    }
+
+    public String getSubField() {
+        return subField;
+    }
+
+    public void setSubField(String subField) {
+        this.subField = subField;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getWebpage() {
+        return webpage;
+    }
+
+    public void setWebpage(String webpage) {
+        this.webpage = webpage;
+    }
+
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    public void setQualifier(String qualifier) {
+        this.qualifier = qualifier;
+    }
+
+    public Boolean getPrimary() {
+        return primary;
+    }
+
+    public void setPrimary(Boolean primary) {
+        this.primary = primary;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof OrganizationImpl)) return false;
+
+        OrganizationImpl that = (OrganizationImpl) o;
+
+        if (address != null ? !address.equals(that.address) : that.address != null) return false;
+        if (description != null ? !description.equals(that.description) : that.description != null) return false;
+        if (endDate != null ? !endDate.equals(that.endDate) : that.endDate != null) return false;
+        if (field != null ? !field.equals(that.field) : that.field != null) return false;
+        if (name != null ? !name.equals(that.name) : that.name != null) return false;
+        if (primary != null ? !primary.equals(that.primary) : that.primary != null) return false;
+        if (qualifier != null ? !qualifier.equals(that.qualifier) : that.qualifier != null) return false;
+        if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) return false;
+        if (subField != null ? !subField.equals(that.subField) : that.subField != null) return false;
+        if (title != null ? !title.equals(that.title) : that.title != null) return false;
+        if (webpage != null ? !webpage.equals(that.webpage) : that.webpage != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = address != null ? address.hashCode() : 0;
+        result = 31 * result + (description != null ? description.hashCode() : 0);
+        result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
+        result = 31 * result + (field != null ? field.hashCode() : 0);
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
+        result = 31 * result + (subField != null ? subField.hashCode() : 0);
+        result = 31 * result + (title != null ? title.hashCode() : 0);
+        result = 31 * result + (webpage != null ? webpage.hashCode() : 0);
+        result = 31 * result + (qualifier != null ? qualifier.hashCode() : 0);
+        result = 31 * result + (primary != null ? primary.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java
new file mode 100644
index 0000000..1439425
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageImpl.java
@@ -0,0 +1,151 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.impl;

+

+import org.apache.rave.portal.model.*;

+

+import java.util.List;

+

+public class PageImpl implements Page {

+    private Long id;

+    private String name;

+    private User owner;

+    private Page parentPage;

+    private List<Page> subPages;

+    private PageLayout pageLayout;

+    private List<Region> regions;

+    private PageType pageType;

+    private List<PageUser> members;

+

+    public PageImpl() {}

+

+    public PageImpl(Long id) {

+        this.id = id;

+    }

+

+    public PageImpl(Long id, User owner) {

+        this.id = id;

+        this.owner = owner;

+    }

+

+    @Override

+    public Long getId() {

+        return id;

+    }

+

+    @Override

+    public void setId(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public String getName() {

+        return name;

+    }

+

+    @Override

+    public void setName(String name) {

+        this.name = name;

+    }

+

+    @Override

+    public User getOwner() {

+        return owner;

+    }

+

+    @Override

+    public void setOwner(User owner) {

+        this.owner = owner;

+    }

+

+    @Override

+    public Page getParentPage() {

+        return parentPage;

+    }

+

+    @Override

+    public void setParentPage(Page parentPage) {

+        this.parentPage = parentPage;

+    }

+

+    @Override

+    public List<Page> getSubPages() {

+        return subPages;

+    }

+

+    @Override

+    public void setSubPages(List<Page> subPages) {

+        this.subPages = subPages;

+    }

+

+    @Override

+    public PageLayout getPageLayout() {

+        return pageLayout;

+    }

+

+    @Override

+    public void setPageLayout(PageLayout pageLayout) {

+        this.pageLayout = pageLayout;

+    }

+

+    @Override

+    public List<Region> getRegions() {

+        return regions;

+    }

+

+    @Override

+    public void setRegions(List<Region> regions) {

+        this.regions = regions;

+    }

+

+    @Override

+    public PageType getPageType() {

+        return pageType;

+    }

+

+    @Override

+    public void setPageType(PageType pageType) {

+        this.pageType = pageType;

+    }

+

+    @Override

+    public List<PageUser> getMembers() {

+        return members;

+    }

+

+    @Override

+    public void setMembers(List<PageUser> members) {

+        this.members = members;

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (obj == null) {

+            return false;

+        }

+        if (getClass() != obj.getClass()) {

+            return false;

+        }

+        final Page other = (Page) obj;

+        if (this.id != other.getId() && (this.id == null || !this.id.equals(other.getId()))) {

+            return false;

+        }

+        return true;

+    }

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageLayoutImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageLayoutImpl.java
new file mode 100644
index 0000000..a03de88
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageLayoutImpl.java
@@ -0,0 +1,75 @@
+package org.apache.rave.portal.model.impl;
+
+
+import org.apache.rave.portal.model.PageLayout;
+
+public class PageLayoutImpl implements PageLayout {
+    private String code;
+    private Long numberOfRegions;
+    private Long renderSequence;
+    private boolean userSelectable;
+
+    public PageLayoutImpl() {  }
+
+    public PageLayoutImpl(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Long getNumberOfRegions() {
+        return numberOfRegions;
+    }
+
+    public void setNumberOfRegions(Long numberOfRegions) {
+        this.numberOfRegions = numberOfRegions;
+    }
+
+    public Long getRenderSequence() {
+        return renderSequence;
+    }
+
+    public void setRenderSequence(Long renderSequence) {
+        this.renderSequence = renderSequence;
+    }
+
+    public boolean isUserSelectable() {
+        return userSelectable;
+    }
+
+    public void setUserSelectable(boolean userSelectable) {
+        this.userSelectable = userSelectable;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PageLayoutImpl)) return false;
+
+        PageLayoutImpl that = (PageLayoutImpl) o;
+
+        if (userSelectable != that.userSelectable) return false;
+        if (code != null ? !code.equals(that.code) : that.code != null) return false;
+        if (numberOfRegions != null ? !numberOfRegions.equals(that.numberOfRegions) : that.numberOfRegions != null)
+            return false;
+        if (renderSequence != null ? !renderSequence.equals(that.renderSequence) : that.renderSequence != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = code != null ? code.hashCode() : 0;
+        result = 31 * result + (numberOfRegions != null ? numberOfRegions.hashCode() : 0);
+        result = 31 * result + (renderSequence != null ? renderSequence.hashCode() : 0);
+        result = 31 * result + (userSelectable ? 1 : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateImpl.java
new file mode 100644
index 0000000..192c089
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateImpl.java
@@ -0,0 +1,135 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.*;
+
+import java.util.List;
+
+public class PageTemplateImpl implements PageTemplate {
+    private Long id;
+    private String name;
+    private String description;
+    private PageType pageType;
+    private PageTemplate parentPageTemplate;
+    private List<PageTemplate> subPageTemplates;
+    private PageLayout pageLayout;
+    private List<PageTemplateRegion> pageTemplateRegions;
+    private long renderSequence;
+    private boolean defaultTemplate;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public PageType getPageType() {
+        return pageType;
+    }
+
+    public void setPageType(PageType pageType) {
+        this.pageType = pageType;
+    }
+
+    public PageTemplate getParentPageTemplate() {
+        return parentPageTemplate;
+    }
+
+    public void setParentPageTemplate(PageTemplate parentPageTemplate) {
+        this.parentPageTemplate = parentPageTemplate;
+    }
+
+    public List<PageTemplate> getSubPageTemplates() {
+        return subPageTemplates;
+    }
+
+    public void setSubPageTemplates(List<PageTemplate> subPageTemplates) {
+        this.subPageTemplates = subPageTemplates;
+    }
+
+    public PageLayout getPageLayout() {
+        return pageLayout;
+    }
+
+    public void setPageLayout(PageLayout pageLayout) {
+        this.pageLayout = pageLayout;
+    }
+
+    public List<PageTemplateRegion> getPageTemplateRegions() {
+        return pageTemplateRegions;
+    }
+
+    public void setPageTemplateRegions(List<PageTemplateRegion> pageTemplateRegions) {
+        this.pageTemplateRegions = pageTemplateRegions;
+    }
+
+    public long getRenderSequence() {
+        return renderSequence;
+    }
+
+    public void setRenderSequence(long renderSequence) {
+        this.renderSequence = renderSequence;
+    }
+
+    public boolean isDefaultTemplate() {
+        return defaultTemplate;
+    }
+
+    public void setDefaultTemplate(boolean defaultTemplate) {
+        this.defaultTemplate = defaultTemplate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PageTemplateImpl)) return false;
+
+        PageTemplateImpl that = (PageTemplateImpl) o;
+
+        if (defaultTemplate != that.defaultTemplate) return false;
+        if (renderSequence != that.renderSequence) return false;
+        if (description != null ? !description.equals(that.description) : that.description != null) return false;
+        if (name != null ? !name.equals(that.name) : that.name != null) return false;
+        if (pageLayout != null ? !pageLayout.equals(that.pageLayout) : that.pageLayout != null) return false;
+        if (pageTemplateRegions != null ? !pageTemplateRegions.equals(that.pageTemplateRegions) : that.pageTemplateRegions != null)
+            return false;
+        if (pageType != that.pageType) return false;
+        if (parentPageTemplate != null ? !parentPageTemplate.equals(that.parentPageTemplate) : that.parentPageTemplate != null)
+            return false;
+        if (subPageTemplates != null ? !subPageTemplates.equals(that.subPageTemplates) : that.subPageTemplates != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (description != null ? description.hashCode() : 0);
+        result = 31 * result + (pageType != null ? pageType.hashCode() : 0);
+        result = 31 * result + (parentPageTemplate != null ? parentPageTemplate.hashCode() : 0);
+        result = 31 * result + (subPageTemplates != null ? subPageTemplates.hashCode() : 0);
+        result = 31 * result + (pageLayout != null ? pageLayout.hashCode() : 0);
+        result = 31 * result + (pageTemplateRegions != null ? pageTemplateRegions.hashCode() : 0);
+        result = 31 * result + (int) (renderSequence ^ (renderSequence >>> 32));
+        result = 31 * result + (defaultTemplate ? 1 : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateRegionImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateRegionImpl.java
new file mode 100644
index 0000000..00ad529
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateRegionImpl.java
@@ -0,0 +1,78 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.*;
+
+import java.util.List;
+
+public class PageTemplateRegionImpl implements PageTemplateRegion {
+    private Long id;
+    private long renderSequence;
+    private PageTemplate pageTemplate;
+    private List<PageTemplateWidget> pageTemplateWidgets;
+    private boolean locked;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public long getRenderSequence() {
+        return renderSequence;
+    }
+
+    public void setRenderSequence(long renderSequence) {
+        this.renderSequence = renderSequence;
+    }
+
+    public PageTemplate getPageTemplate() {
+        return pageTemplate;
+    }
+
+    public void setPageTemplate(PageTemplate pageTemplate) {
+        this.pageTemplate = pageTemplate;
+    }
+
+    public List<PageTemplateWidget> getPageTemplateWidgets() {
+        return pageTemplateWidgets;
+    }
+
+    public void setPageTemplateWidgets(List<PageTemplateWidget> pageTemplateWidgets) {
+        this.pageTemplateWidgets = pageTemplateWidgets;
+    }
+
+    public boolean isLocked() {
+        return locked;
+    }
+
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PageTemplateRegionImpl)) return false;
+
+        PageTemplateRegionImpl that = (PageTemplateRegionImpl) o;
+
+        if (locked != that.locked) return false;
+        if (renderSequence != that.renderSequence) return false;
+        if (pageTemplate != null ? !pageTemplate.equals(that.pageTemplate) : that.pageTemplate != null) return false;
+        if (pageTemplateWidgets != null ? !pageTemplateWidgets.equals(that.pageTemplateWidgets) : that.pageTemplateWidgets != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = (int) (renderSequence ^ (renderSequence >>> 32));
+        result = 31 * result + (pageTemplate != null ? pageTemplate.hashCode() : 0);
+        result = 31 * result + (pageTemplateWidgets != null ? pageTemplateWidgets.hashCode() : 0);
+        result = 31 * result + (locked ? 1 : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateWidgetImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateWidgetImpl.java
new file mode 100644
index 0000000..7d906ad
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageTemplateWidgetImpl.java
@@ -0,0 +1,88 @@
+package org.apache.rave.portal.model.impl;
+
+
+import org.apache.rave.portal.model.*;
+
+public class PageTemplateWidgetImpl implements PageTemplateWidget {
+    private Long id;
+    private PageTemplateRegion pageTemplateRegion;
+    private long renderSequence;
+    private Widget widget;
+    private boolean locked;
+    private boolean hideChrome;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public PageTemplateRegion getPageTemplateRegion() {
+        return pageTemplateRegion;
+    }
+
+    public void setPageTemplateRegion(PageTemplateRegion pageTemplateRegion) {
+        this.pageTemplateRegion = pageTemplateRegion;
+    }
+
+    public long getRenderSeq() {
+        return renderSequence;
+    }
+
+    public void setRenderSeq(long renderSequence) {
+        this.renderSequence = renderSequence;
+    }
+
+    public Widget getWidget() {
+        return widget;
+    }
+
+    public void setWidget(Widget widget) {
+        this.widget = widget;
+    }
+
+    public boolean isLocked() {
+        return locked;
+    }
+
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    public boolean isHideChrome() {
+        return hideChrome;
+    }
+
+    public void setHideChrome(boolean hideChrome) {
+        this.hideChrome = hideChrome;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PageTemplateWidgetImpl)) return false;
+
+        PageTemplateWidgetImpl that = (PageTemplateWidgetImpl) o;
+
+        if (hideChrome != that.hideChrome) return false;
+        if (locked != that.locked) return false;
+        if (renderSequence != that.renderSequence) return false;
+        if (pageTemplateRegion != null ? !pageTemplateRegion.equals(that.pageTemplateRegion) : that.pageTemplateRegion != null)
+            return false;
+        if (widget != null ? !widget.equals(that.widget) : that.widget != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = pageTemplateRegion != null ? pageTemplateRegion.hashCode() : 0;
+        result = 31 * result + (int) (renderSequence ^ (renderSequence >>> 32));
+        result = 31 * result + (widget != null ? widget.hashCode() : 0);
+        result = 31 * result + (locked ? 1 : 0);
+        result = 31 * result + (hideChrome ? 1 : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageUserImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageUserImpl.java
new file mode 100644
index 0000000..ec8c51e
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PageUserImpl.java
@@ -0,0 +1,108 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.impl;

+

+import org.apache.rave.portal.model.*;

+

+public class PageUserImpl implements PageUser {

+    private Long id;

+    private User user;

+    private Page page;

+    private boolean editor;

+    private Long renderSequence;

+    private PageInvitationStatus pageStatus;

+

+    public PageUserImpl(){}

+

+    public PageUserImpl(Long id){

+        this.id = id;

+    }

+

+    public PageUserImpl(User user, Page page){

+        this.user = user;

+        this.page = page;

+    }

+

+    public PageUserImpl(User user, Page page, long sequence){

+        this.user = user;

+        this.page = page;

+        this.renderSequence = sequence;

+    }

+

+

+    @Override

+    public Long getId() {

+        return id;

+    }

+

+    @Override

+    public void setId(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public User getUser() {

+        return user;

+    }

+

+    @Override

+    public void setUser(User user) {

+        this.user = user;

+    }

+

+    @Override

+    public Page getPage() {

+        return page;

+    }

+

+    @Override

+    public void setPage(Page page) {

+        this.page = page;

+    }

+

+    @Override

+    public boolean isEditor() {

+        return editor;

+    }

+

+    @Override

+    public void setEditor(boolean editor) {

+        this.editor = editor;

+    }

+

+    @Override

+    public Long getRenderSequence() {

+        return renderSequence;

+    }

+

+    @Override

+    public void setRenderSequence(Long renderSequence) {

+        this.renderSequence = renderSequence;

+    }

+

+    @Override

+    public PageInvitationStatus getPageStatus() {

+        return pageStatus;

+    }

+

+    @Override

+    public void setPageStatus(PageInvitationStatus pageStatus) {

+        this.pageStatus = pageStatus;

+    }

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PersonImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PersonImpl.java
new file mode 100644
index 0000000..958e2c1
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PersonImpl.java
@@ -0,0 +1,195 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.*;
+
+import java.util.List;
+
+public class PersonImpl implements Person {
+
+    protected String username;
+    protected String email;
+    protected String displayName;
+    protected String additionalName;
+    protected String familyName;
+    protected String givenName;
+    protected String honorificPrefix;
+    protected String honorificSuffix;
+    protected String preferredName;
+    protected String aboutMe;
+    protected String status;
+    protected List<Address> addresses;
+    protected List<Organization> organizations;
+    protected List<PersonProperty> properties;
+    protected List<Person> friends;
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getAdditionalName() {
+        return additionalName;
+    }
+
+    public void setAdditionalName(String additionalName) {
+        this.additionalName = additionalName;
+    }
+
+    public String getFamilyName() {
+        return familyName;
+    }
+
+    public void setFamilyName(String familyName) {
+        this.familyName = familyName;
+    }
+
+    public String getGivenName() {
+        return givenName;
+    }
+
+    public void setGivenName(String givenName) {
+        this.givenName = givenName;
+    }
+
+    public String getHonorificPrefix() {
+        return honorificPrefix;
+    }
+
+    public void setHonorificPrefix(String honorificPrefix) {
+        this.honorificPrefix = honorificPrefix;
+    }
+
+    public String getHonorificSuffix() {
+        return honorificSuffix;
+    }
+
+    public void setHonorificSuffix(String honorificSuffix) {
+        this.honorificSuffix = honorificSuffix;
+    }
+
+    public String getPreferredName() {
+        return preferredName;
+    }
+
+    public void setPreferredName(String preferredName) {
+        this.preferredName = preferredName;
+    }
+
+    public String getAboutMe() {
+        return aboutMe;
+    }
+
+    public void setAboutMe(String aboutMe) {
+        this.aboutMe = aboutMe;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public List<Address> getAddresses() {
+        return addresses;
+    }
+
+    public void setAddresses(List<Address> addresses) {
+        this.addresses = addresses;
+    }
+
+    public List<Organization> getOrganizations() {
+        return organizations;
+    }
+
+    public void setOrganizations(List<Organization> organizations) {
+        this.organizations = organizations;
+    }
+
+    public List<PersonProperty> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<PersonProperty> properties) {
+        this.properties = properties;
+    }
+
+    public List<Person> getFriends() {
+        return friends;
+    }
+
+    public void setFriends(List<Person> friends) {
+        this.friends = friends;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PersonImpl)) return false;
+
+        PersonImpl person = (PersonImpl) o;
+
+        if (aboutMe != null ? !aboutMe.equals(person.aboutMe) : person.aboutMe != null) return false;
+        if (additionalName != null ? !additionalName.equals(person.additionalName) : person.additionalName != null)
+            return false;
+        if (addresses != null ? !addresses.equals(person.addresses) : person.addresses != null) return false;
+        if (displayName != null ? !displayName.equals(person.displayName) : person.displayName != null) return false;
+        if (email != null ? !email.equals(person.email) : person.email != null) return false;
+        if (familyName != null ? !familyName.equals(person.familyName) : person.familyName != null) return false;
+        if (friends != null ? !friends.equals(person.friends) : person.friends != null) return false;
+        if (givenName != null ? !givenName.equals(person.givenName) : person.givenName != null) return false;
+        if (honorificPrefix != null ? !honorificPrefix.equals(person.honorificPrefix) : person.honorificPrefix != null)
+            return false;
+        if (honorificSuffix != null ? !honorificSuffix.equals(person.honorificSuffix) : person.honorificSuffix != null)
+            return false;
+        if (organizations != null ? !organizations.equals(person.organizations) : person.organizations != null)
+            return false;
+        if (preferredName != null ? !preferredName.equals(person.preferredName) : person.preferredName != null)
+            return false;
+        if (properties != null ? !properties.equals(person.properties) : person.properties != null) return false;
+        if (status != null ? !status.equals(person.status) : person.status != null) return false;
+        if (username != null ? !username.equals(person.username) : person.username != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = username != null ? username.hashCode() : 0;
+        result = 31 * result + (email != null ? email.hashCode() : 0);
+        result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
+        result = 31 * result + (additionalName != null ? additionalName.hashCode() : 0);
+        result = 31 * result + (familyName != null ? familyName.hashCode() : 0);
+        result = 31 * result + (givenName != null ? givenName.hashCode() : 0);
+        result = 31 * result + (honorificPrefix != null ? honorificPrefix.hashCode() : 0);
+        result = 31 * result + (honorificSuffix != null ? honorificSuffix.hashCode() : 0);
+        result = 31 * result + (preferredName != null ? preferredName.hashCode() : 0);
+        result = 31 * result + (aboutMe != null ? aboutMe.hashCode() : 0);
+        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (addresses != null ? addresses.hashCode() : 0);
+        result = 31 * result + (organizations != null ? organizations.hashCode() : 0);
+        result = 31 * result + (properties != null ? properties.hashCode() : 0);
+        result = 31 * result + (friends != null ? friends.hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PersonPropertyImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PersonPropertyImpl.java
new file mode 100644
index 0000000..1e4b019
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PersonPropertyImpl.java
@@ -0,0 +1,102 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.PersonProperty;
+
+/** **/
+public class PersonPropertyImpl implements PersonProperty {
+
+    private Long id;
+    private String type;
+    private String value;
+    private String qualifier;
+    private String extendedValue;
+    private Boolean primary;
+
+    public PersonPropertyImpl() {}
+
+    public PersonPropertyImpl(Long id, String type, String value, String extendedValue, String qualifier, Boolean primary) {
+        this.id = id;
+        this.type = type;
+        this.value = value;
+        this.qualifier = qualifier;
+        this.primary = primary;
+        this.extendedValue = extendedValue;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    public void setQualifier(String qualifier) {
+        this.qualifier = qualifier;
+    }
+
+    public String getExtendedValue() {
+        return extendedValue;
+    }
+
+    public void setExtendedValue(String extendedValue) {
+        this.extendedValue = extendedValue;
+    }
+
+    public Boolean getPrimary() {
+        return primary;
+    }
+
+    public void setPrimary(Boolean primary) {
+        this.primary = primary;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PersonPropertyImpl)) return false;
+
+        PersonPropertyImpl that = (PersonPropertyImpl) o;
+
+        if (extendedValue != null ? !extendedValue.equals(that.extendedValue) : that.extendedValue != null)
+            return false;
+        if (id != null ? !id.equals(that.id) : that.id != null) return false;
+        if (primary != null ? !primary.equals(that.primary) : that.primary != null) return false;
+        if (qualifier != null ? !qualifier.equals(that.qualifier) : that.qualifier != null) return false;
+        if (type != null ? !type.equals(that.type) : that.type != null) return false;
+        if (value != null ? !value.equals(that.value) : that.value != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (type != null ? type.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        result = 31 * result + (qualifier != null ? qualifier.hashCode() : 0);
+        result = 31 * result + (extendedValue != null ? extendedValue.hashCode() : 0);
+        result = 31 * result + (primary != null ? primary.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PortalPreferenceImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PortalPreferenceImpl.java
new file mode 100644
index 0000000..21392ae
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/PortalPreferenceImpl.java
@@ -0,0 +1,76 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.exception.NotSupportedException;
+import org.apache.rave.portal.model.PortalPreference;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+public class PortalPreferenceImpl implements PortalPreference {
+    private String key;
+    private List<String> values = new LinkedList<String>();
+
+    public PortalPreferenceImpl() {}
+
+    public PortalPreferenceImpl(String key, List<String> values) {
+        this.key = key;
+        this.values = values;
+    }
+
+    public PortalPreferenceImpl(String key, String values) {
+        this.key = key;
+        this.values.add(values);
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    public List<String> getValues() {
+        return values;
+    }
+
+    public void setValues(List<String> values) {
+        this.values = values;
+    }
+
+    public String getValue() {
+        if (values.isEmpty()) {
+            return null;
+        } else if (values.size() == 1) {
+            return values.get(0);
+        }
+        throw new NotSupportedException("Cannot return single value for a List of size " + values.size());
+    }
+
+    public void setValue(String value) {
+        List<String> values = new ArrayList<String>();
+        values.add(value);
+        this.values = values;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PortalPreferenceImpl)) return false;
+
+        PortalPreferenceImpl that = (PortalPreferenceImpl) o;
+
+        if (key != null ? !key.equals(that.key) : that.key != null) return false;
+        if (values != null ? !values.equals(that.values) : that.values != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = key != null ? key.hashCode() : 0;
+        result = 31 * result + (values != null ? values.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionImpl.java
new file mode 100644
index 0000000..5036b90
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionImpl.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.Page;
+import org.apache.rave.portal.model.Region;
+import org.apache.rave.portal.model.RegionWidget;
+
+import java.util.List;
+
+public class RegionImpl implements Region {
+    private Long id;
+    private Page page;
+    private Boolean locked = false;
+    private Integer renderOrder = 0;
+    private List<RegionWidget> regionWidgets;
+
+    public RegionImpl() {
+
+    }
+
+    public RegionImpl(Long id, Page page, int renderOrder) {
+        this.id = id;
+        this.page = page;
+        this.renderOrder = renderOrder;
+    }
+
+    public RegionImpl(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public Page getPage() {
+        return page;
+    }
+
+    @Override
+    public void setPage(Page page) {
+        this.page = page;
+    }
+
+    @Override
+    public int getRenderOrder() {
+        return renderOrder;
+    }
+
+    @Override
+    public void setRenderOrder(int renderOrder) {
+        this.renderOrder = renderOrder;
+    }
+
+    @Override
+    public List<RegionWidget> getRegionWidgets() {
+        return regionWidgets;
+    }
+
+    @Override
+    public void setRegionWidgets(List<RegionWidget> regionWidgets) {
+        this.regionWidgets = regionWidgets;
+    }
+
+    @Override
+    public boolean isLocked() {
+        return locked;
+    }
+
+    @Override
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof RegionImpl)) return false;
+
+        RegionImpl region = (RegionImpl) o;
+
+        if (id != null ? !id.equals(region.id) : region.id != null) return false;
+        if (locked != null ? !locked.equals(region.locked) : region.locked != null)
+            return false;
+        if (renderOrder != null ? !renderOrder.equals(region.renderOrder) : region.renderOrder != null) return false;
+        if (regionWidgets != null ? !regionWidgets.equals(region.regionWidgets) : region.regionWidgets != null)
+            return false;
+        if (page != null ? !page.equals(region.page) : region.page != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = (page != null ? page.hashCode() : 0);
+        result = 31 * result + (regionWidgets != null ? regionWidgets.hashCode() : 0);
+        result = 31 * result + (id != null ? id.hashCode() : 0);
+        result = 31 * result + (renderOrder != null ? renderOrder.hashCode() : 0);
+        result = 31 * result + (locked != null ? locked.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "RegionImpl{" +
+                "id=" + id +
+                ", page=" + ((page == null) ? null : page.getId()) +
+                ", locked=" + locked +
+                ", renderOrder=" + renderOrder +
+                '}';
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionWidgetImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionWidgetImpl.java
new file mode 100644
index 0000000..a44b32a
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionWidgetImpl.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.Region;
+import org.apache.rave.portal.model.RegionWidget;
+import org.apache.rave.portal.model.RegionWidgetPreference;
+import org.apache.rave.portal.model.Widget;
+
+import java.util.List;
+
+public class RegionWidgetImpl implements RegionWidget {
+    private Long id;
+    private Widget widget;
+    private Region region;
+    private String renderPosition;
+    private Integer renderOrder = 0;
+    private Boolean collapsed = false;
+    private List<RegionWidgetPreference> preferences;
+    private Boolean locked = false;
+    private Boolean hideChrome = false;
+
+    public RegionWidgetImpl() {
+
+    }
+
+    public RegionWidgetImpl(Long id) {
+        this.id = id;
+    }
+
+    public RegionWidgetImpl(Long id, Widget widget, Region region) {
+        this.id = id;
+        this.widget = widget;
+        this.region = region;
+    }
+
+    public RegionWidgetImpl(Long id, Widget widget, Region region, int renderOrder) {
+        this.id = id;
+        this.widget = widget;
+        this.region = region;
+        this.renderOrder = renderOrder;
+    }
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public Widget getWidget() {
+        return widget;
+    }
+
+    @Override
+    public void setWidget(Widget widget) {
+        this.widget = widget;
+    }
+
+    @Override
+    public Region getRegion() {
+        return region;
+    }
+
+    @Override
+    public void setRegion(Region region) {
+        this.region = region;
+    }
+
+    @Override
+    public String getRenderPosition() {
+        return renderPosition;
+    }
+
+    @Override
+    public void setRenderPosition(String renderPosition) {
+        this.renderPosition = renderPosition;
+    }
+
+    @Override
+    public int getRenderOrder() {
+        return renderOrder;
+    }
+
+    @Override
+    public void setRenderOrder(int renderOrder) {
+        this.renderOrder = renderOrder;
+    }
+
+    @Override
+    public boolean isCollapsed() {
+        return collapsed;
+    }
+
+    @Override
+    public void setCollapsed(boolean collapsed) {
+        this.collapsed = collapsed;
+    }
+
+    @Override
+    public List<RegionWidgetPreference> getPreferences() {
+        return preferences;
+    }
+
+    @Override
+    public void setPreferences(List<RegionWidgetPreference> preferences) {
+        this.preferences = preferences;
+    }
+
+    @Override
+    public boolean isLocked() {
+        return locked;
+    }
+
+    @Override
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    @Override
+    public boolean isHideChrome() {
+        return hideChrome;
+    }
+
+    @Override
+    public void setHideChrome(boolean hideChrome) {
+        this.hideChrome = hideChrome;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof RegionWidgetImpl)) return false;
+
+        RegionWidgetImpl rw = (RegionWidgetImpl) o;
+
+        if (id != null ? !id.equals(rw.id) : rw.id != null) return false;
+        if (locked != null ? !locked.equals(rw.locked) : rw.locked != null)
+            return false;
+        if (renderOrder != null ? !renderOrder.equals(rw.renderOrder) : rw.renderOrder != null) return false;
+        if (widget != null ? !widget.equals(rw.widget) : rw.widget != null)
+            return false;
+        if (region != null ? !region.equals(rw.region) : rw.region != null) return false;
+        if (hideChrome != null ? !hideChrome.equals(rw.hideChrome) : rw.hideChrome != null) return false;
+        if (preferences != null ? !preferences.equals(rw.preferences) : rw.preferences != null) return false;
+        if (collapsed != null ? !collapsed.equals(rw.collapsed) : rw.collapsed != null) return false;
+        if (renderPosition != null ? !renderPosition.equals(rw.renderPosition) : rw.renderPosition != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = (widget != null ? widget.hashCode() : 0);
+        result = 31 * result + (preferences != null ? preferences.hashCode() : 0);
+        result = 31 * result + (id != null ? id.hashCode() : 0);
+        result = 31 * result + (renderOrder != null ? renderOrder.hashCode() : 0);
+        result = 31 * result + (locked != null ? locked.hashCode() : 0);
+        result = 31 * result + (renderPosition != null ? renderPosition.hashCode() : 0);
+        result = 31 * result + (region != null ? region.hashCode() : 0);
+        result = 31 * result + (hideChrome != null ? hideChrome.hashCode() : 0);
+        result = 31 * result + (collapsed != null ? collapsed.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "RegionWidgetImpl{" +
+                "id=" + id +
+                ", widget=" + ((widget == null) ? null : widget.getId())  +
+                ", region=" + ((region == null) ? null : region.getId()) +
+                ", renderPosition='" + renderPosition + '\'' +
+                ", renderOrder=" + renderOrder +
+                ", collapsed=" + collapsed +
+                ", locked=" + locked +
+                ", hideChrome=" + hideChrome +
+                '}';
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionWidgetPreferenceImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionWidgetPreferenceImpl.java
new file mode 100644
index 0000000..ebd5131
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/RegionWidgetPreferenceImpl.java
@@ -0,0 +1,66 @@
+package org.apache.rave.portal.model.impl;
+
+
+import org.apache.rave.portal.model.RegionWidgetPreference;
+
+public class RegionWidgetPreferenceImpl implements RegionWidgetPreference {
+
+    private Long regionWidgetId;
+    private String name;
+    private String value;
+
+    public RegionWidgetPreferenceImpl() { }
+
+    public RegionWidgetPreferenceImpl(Long regionWidgetId, String name, String value) {
+        this.regionWidgetId = regionWidgetId;
+        this.name = name;
+        this.value = value;
+    }
+
+    public Long getRegionWidgetId() {
+        return regionWidgetId;
+    }
+
+    public void setRegionWidgetId(Long regionWidgetId) {
+        this.regionWidgetId = regionWidgetId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof RegionWidgetPreferenceImpl)) return false;
+
+        RegionWidgetPreferenceImpl that = (RegionWidgetPreferenceImpl) o;
+
+        if (name != null ? !name.equals(that.name) : that.name != null) return false;
+        if (regionWidgetId != null ? !regionWidgetId.equals(that.regionWidgetId) : that.regionWidgetId != null)
+            return false;
+        if (value != null ? !value.equals(that.value) : that.value != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = regionWidgetId != null ? regionWidgetId.hashCode() : 0;
+        result = 31 * result + (name != null ? name.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/TagImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/TagImpl.java
new file mode 100644
index 0000000..2f01e92
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/TagImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * 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.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.Tag;
+import org.apache.rave.portal.model.WidgetTag;
+
+import java.util.List;
+
+public class TagImpl implements Tag {
+
+    private String keyword;
+    private List<WidgetTag> widgets;
+
+    public TagImpl(String keyword, List<WidgetTag> widgets) {
+        this.keyword = keyword;
+        this.widgets = widgets;
+    }
+
+    public TagImpl(String keyword) {
+        this.keyword = keyword;
+    }
+
+    public TagImpl() {
+    }
+
+    @Override
+    public String getKeyword() {
+        return this.keyword;
+    }
+
+    @Override
+    public void setKeyword(String keyword) {
+        this.keyword = keyword;
+    }
+
+    @Override
+    public List<WidgetTag> getWidgets() {
+        return this.widgets;
+    }
+
+    @Override
+    public void setWidgets(List<WidgetTag> widgets) {
+        this.widgets = widgets;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/UserImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/UserImpl.java
new file mode 100644
index 0000000..0ba1fcc
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/UserImpl.java
@@ -0,0 +1,235 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.PageLayout;
+import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.security.core.GrantedAuthority;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+public class UserImpl extends PersonImpl implements User {
+    private Long id;
+    private String password;
+    private boolean expired;
+    private boolean credsExpired;
+    private boolean locked;
+    private boolean enabled;
+    private String openId;
+    private String forgotPasswordHash;
+    private Date forgotPasswordTime;
+    private PageLayout defaultPageLayout;
+    private String confirmPassword;
+    private String defaultPageLayoutCode;
+    private List<Authority> authorities = new ArrayList<Authority>();
+
+    public UserImpl() {}
+
+    public UserImpl(Long id) {
+        this.id = id;
+    }
+
+    public UserImpl(Long userid, String username) {
+        this.id = userid;
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public boolean isAccountNonLocked() {
+        return !locked;
+    }
+
+    public boolean isExpired() {
+        return expired;
+    }
+
+    public void setExpired(boolean expired) {
+        this.expired = expired;
+    }
+
+    public boolean isLocked() {
+        return locked;
+    }
+
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    public boolean isCredentialsNonExpired() {
+        return !credsExpired;
+    }
+
+    public void setCredsExpired(boolean credsExpired) {
+        this.credsExpired = credsExpired;
+    }
+    public boolean isAccountNonExpired() {
+        return !expired;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public String getOpenId() {
+        return openId;
+    }
+
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
+    public String getForgotPasswordHash() {
+        return forgotPasswordHash;
+    }
+
+    public void setForgotPasswordHash(String forgotPasswordHash) {
+        this.forgotPasswordHash = forgotPasswordHash;
+    }
+
+    public Date getForgotPasswordTime() {
+        return forgotPasswordTime;
+    }
+
+    public void setForgotPasswordTime(Date forgotPasswordTime) {
+        this.forgotPasswordTime = forgotPasswordTime;
+    }
+
+    public PageLayout getDefaultPageLayout() {
+        return defaultPageLayout;
+    }
+
+    public void setDefaultPageLayout(PageLayout defaultPageLayout) {
+        this.defaultPageLayout = defaultPageLayout;
+    }
+
+    public String getConfirmPassword() {
+        return confirmPassword;
+    }
+
+    public void setConfirmPassword(String confirmPassword) {
+        this.confirmPassword = confirmPassword;
+    }
+
+    public Person toPerson() {
+        PersonImpl p = new PersonImpl();
+        p.setAboutMe(this.getAboutMe());
+        p.setAdditionalName(this.getAdditionalName());
+        p.setAddresses(this.getAddresses());
+        p.setDisplayName(this.getDisplayName());
+        p.setEmail(this.getEmail());
+        p.setFamilyName(this.getFamilyName());
+        p.setFriends(this.getFriends());
+        p.setGivenName(this.getGivenName());
+        p.setHonorificPrefix(this.getHonorificPrefix());
+        p.setHonorificSuffix(this.getHonorificSuffix());
+        p.setOrganizations(this.getOrganizations());
+        p.setPreferredName(this.getPreferredName());
+        p.setProperties(this.getProperties());
+        p.setStatus(this.getStatus());
+        p.setUsername(this.getUsername());
+        return p;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+
+    public String getDefaultPageLayoutCode() {
+        return defaultPageLayoutCode;
+    }
+
+    public void setDefaultPageLayoutCode(String defaultPageLayoutCode) {
+        this.defaultPageLayoutCode = defaultPageLayoutCode;
+    }
+
+    public Collection<GrantedAuthority> getAuthorities() {
+        return CollectionUtils.<GrantedAuthority>toBaseTypedList(authorities);
+    }
+
+    public void addAuthority(Authority authority) {
+        this.authorities.add(authority);
+    }
+
+    public void removeAuthority(Authority authority) {
+       this.authorities.remove(authority);
+    }
+
+    public void setAuthorities(Collection<Authority> authorities) {
+        if(this.authorities == null) {
+            this.authorities = new ArrayList<Authority>();
+        }
+        this.authorities.clear();
+        if(authorities != null) {
+            this.authorities.addAll(authorities);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof UserImpl)) return false;
+        if (!super.equals(o)) return false;
+
+        UserImpl user = (UserImpl) o;
+
+        if (credsExpired != user.credsExpired) return false;
+        if (enabled != user.enabled) return false;
+        if (expired != user.expired) return false;
+        if (locked != user.locked) return false;
+        if (authorities != null ? !authorities.equals(user.authorities) : user.authorities != null) return false;
+        if (confirmPassword != null ? !confirmPassword.equals(user.confirmPassword) : user.confirmPassword != null)
+            return false;
+        if (defaultPageLayout != null ? !defaultPageLayout.equals(user.defaultPageLayout) : user.defaultPageLayout != null)
+            return false;
+        if (defaultPageLayoutCode != null ? !defaultPageLayoutCode.equals(user.defaultPageLayoutCode) : user.defaultPageLayoutCode != null)
+            return false;
+        if (forgotPasswordHash != null ? !forgotPasswordHash.equals(user.forgotPasswordHash) : user.forgotPasswordHash != null)
+            return false;
+        if (forgotPasswordTime != null ? !forgotPasswordTime.equals(user.forgotPasswordTime) : user.forgotPasswordTime != null)
+            return false;
+        if (id != null ? !id.equals(user.id) : user.id != null) return false;
+        if (openId != null ? !openId.equals(user.openId) : user.openId != null) return false;
+        if (password != null ? !password.equals(user.password) : user.password != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + (id != null ? id.hashCode() : 0);
+        result = 31 * result + (password != null ? password.hashCode() : 0);
+        result = 31 * result + (expired ? 1 : 0);
+        result = 31 * result + (credsExpired ? 1 : 0);
+        result = 31 * result + (locked ? 1 : 0);
+        result = 31 * result + (enabled ? 1 : 0);
+        result = 31 * result + (openId != null ? openId.hashCode() : 0);
+        result = 31 * result + (forgotPasswordHash != null ? forgotPasswordHash.hashCode() : 0);
+        result = 31 * result + (forgotPasswordTime != null ? forgotPasswordTime.hashCode() : 0);
+        result = 31 * result + (defaultPageLayout != null ? defaultPageLayout.hashCode() : 0);
+        result = 31 * result + (confirmPassword != null ? confirmPassword.hashCode() : 0);
+        result = 31 * result + (defaultPageLayoutCode != null ? defaultPageLayoutCode.hashCode() : 0);
+        result = 31 * result + (authorities != null ? authorities.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetCommentImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetCommentImpl.java
new file mode 100644
index 0000000..5c4843f
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetCommentImpl.java
@@ -0,0 +1,102 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.impl;

+

+

+import org.apache.rave.portal.model.*;

+

+import java.util.Date;

+

+public class WidgetCommentImpl implements WidgetComment {

+    private Long id;

+    private Long widgetId;

+    private User user;

+    private String text;

+    private Date lastModifiedDate;

+    private Date createdDate;

+

+    @Override

+    public Long getId() {

+        return id;

+    }

+

+    @Override

+    public void setId(Long id) {

+        this.id = id;

+    }

+

+    @Override

+    public Long getWidgetId() {

+        return widgetId;

+    }

+

+    @Override

+    public void setWidgetId(Long widgetId) {

+        this.widgetId = widgetId;

+    }

+

+    @Override

+    public User getUser() {

+        return user;

+    }

+

+    @Override

+    public void setUser(User user) {

+        this.user = user;

+    }

+

+    @Override

+    public String getText() {

+        return text;

+    }

+

+    @Override

+    public void setText(String text) {

+        this.text = text;

+    }

+

+    @Override

+    public Date getLastModifiedDate() {

+        return lastModifiedDate;

+    }

+

+    @Override

+    public void setLastModifiedDate(Date lastModifiedDate) {

+        this.lastModifiedDate = lastModifiedDate;

+    }

+

+    @Override

+    public Date getCreatedDate() {

+        return createdDate;

+    }

+

+    @Override

+    public void setCreatedDate(Date createdDate) {

+        this.createdDate = createdDate;

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (this == obj) return true;

+        if (obj == null || getClass() != obj.getClass()) return false;

+        WidgetCommentImpl comment = (WidgetCommentImpl) obj;

+        if (id != null ? !id.equals(comment.id) : comment.id != null) return false;

+        return true;

+    }

+}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetImpl.java
new file mode 100644
index 0000000..3be27c8
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetImpl.java
@@ -0,0 +1,247 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.*;
+
+import java.util.List;
+
+public class WidgetImpl implements Widget {
+    private Long id;
+    private String title;
+    private String titleUrl;
+    private String url;
+    private String thumbnailUrl;
+    private String screenshotUrl;
+    private String type;
+    private String author;
+    private String authorEmail;
+    private String description;
+    private WidgetStatus widgetStatus;
+    private List<WidgetComment> comments;
+    private User owner;
+    private boolean disableRendering;
+    private String disableRenderingMessage;
+    private List<WidgetRating> ratings;
+    private List<WidgetTag> tags;
+    private List<Category> categories;
+    private boolean featured;
+
+    public WidgetImpl() {}
+
+    public WidgetImpl(long id) {
+        this.id = id;
+    }
+
+    public WidgetImpl(long id, String url) {
+        this.id = id;
+        this.url = url;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getTitleUrl() {
+        return titleUrl;
+    }
+
+    public void setTitleUrl(String titleUrl) {
+        this.titleUrl = titleUrl;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getThumbnailUrl() {
+        return thumbnailUrl;
+    }
+
+    public void setThumbnailUrl(String thumbnailUrl) {
+        this.thumbnailUrl = thumbnailUrl;
+    }
+
+    public String getScreenshotUrl() {
+        return screenshotUrl;
+    }
+
+    public void setScreenshotUrl(String screenshotUrl) {
+        this.screenshotUrl = screenshotUrl;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getAuthor() {
+        return author;
+    }
+
+    public void setAuthor(String author) {
+        this.author = author;
+    }
+
+    public String getAuthorEmail() {
+        return authorEmail;
+    }
+
+    public void setAuthorEmail(String authorEmail) {
+        this.authorEmail = authorEmail;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public WidgetStatus getWidgetStatus() {
+        return widgetStatus;
+    }
+
+    public void setWidgetStatus(WidgetStatus widgetStatus) {
+        this.widgetStatus = widgetStatus;
+    }
+
+    public List<WidgetComment> getComments() {
+        return comments;
+    }
+
+    public void setComments(List<WidgetComment> comments) {
+        this.comments = comments;
+    }
+
+    public User getOwner() {
+        return owner;
+    }
+
+    public void setOwner(User owner) {
+        this.owner = owner;
+    }
+
+    public boolean isDisableRendering() {
+        return disableRendering;
+    }
+
+    public void setDisableRendering(boolean disableRendering) {
+        this.disableRendering = disableRendering;
+    }
+
+    public String getDisableRenderingMessage() {
+        return disableRenderingMessage;
+    }
+
+    public void setDisableRenderingMessage(String disableRenderingMessage) {
+        this.disableRenderingMessage = disableRenderingMessage;
+    }
+
+    public List<WidgetRating> getRatings() {
+        return ratings;
+    }
+
+    public void setRatings(List<WidgetRating> ratings) {
+        this.ratings = ratings;
+    }
+
+    public List<WidgetTag> getTags() {
+        return tags;
+    }
+
+    public void setTags(List<WidgetTag> tags) {
+        this.tags = tags;
+    }
+
+    public List<Category> getCategories() {
+        return categories;
+    }
+
+    public void setCategories(List<Category> categories) {
+        this.categories = categories;
+    }
+
+    public boolean isFeatured() {
+        return featured;
+    }
+
+    public void setFeatured(boolean featured) {
+        this.featured = featured;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof WidgetImpl)) return false;
+
+        WidgetImpl widget = (WidgetImpl) o;
+
+        if (disableRendering != widget.disableRendering) return false;
+        if (featured != widget.featured) return false;
+        if (author != null ? !author.equals(widget.author) : widget.author != null) return false;
+        if (authorEmail != null ? !authorEmail.equals(widget.authorEmail) : widget.authorEmail != null) return false;
+        if (categories != null ? !categories.equals(widget.categories) : widget.categories != null) return false;
+        if (comments != null ? !comments.equals(widget.comments) : widget.comments != null) return false;
+        if (description != null ? !description.equals(widget.description) : widget.description != null) return false;
+        if (disableRenderingMessage != null ? !disableRenderingMessage.equals(widget.disableRenderingMessage) : widget.disableRenderingMessage != null)
+            return false;
+        if (id != null ? !id.equals(widget.id) : widget.id != null) return false;
+        if (owner != null ? !owner.equals(widget.owner) : widget.owner != null) return false;
+        if (ratings != null ? !ratings.equals(widget.ratings) : widget.ratings != null) return false;
+        if (screenshotUrl != null ? !screenshotUrl.equals(widget.screenshotUrl) : widget.screenshotUrl != null)
+            return false;
+        if (tags != null ? !tags.equals(widget.tags) : widget.tags != null) return false;
+        if (thumbnailUrl != null ? !thumbnailUrl.equals(widget.thumbnailUrl) : widget.thumbnailUrl != null)
+            return false;
+        if (title != null ? !title.equals(widget.title) : widget.title != null) return false;
+        if (titleUrl != null ? !titleUrl.equals(widget.titleUrl) : widget.titleUrl != null) return false;
+        if (type != null ? !type.equals(widget.type) : widget.type != null) return false;
+        if (url != null ? !url.equals(widget.url) : widget.url != null) return false;
+        if (widgetStatus != widget.widgetStatus) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (title != null ? title.hashCode() : 0);
+        result = 31 * result + (titleUrl != null ? titleUrl.hashCode() : 0);
+        result = 31 * result + (url != null ? url.hashCode() : 0);
+        result = 31 * result + (thumbnailUrl != null ? thumbnailUrl.hashCode() : 0);
+        result = 31 * result + (screenshotUrl != null ? screenshotUrl.hashCode() : 0);
+        result = 31 * result + (type != null ? type.hashCode() : 0);
+        result = 31 * result + (author != null ? author.hashCode() : 0);
+        result = 31 * result + (authorEmail != null ? authorEmail.hashCode() : 0);
+        result = 31 * result + (description != null ? description.hashCode() : 0);
+        result = 31 * result + (widgetStatus != null ? widgetStatus.hashCode() : 0);
+        result = 31 * result + (comments != null ? comments.hashCode() : 0);
+        result = 31 * result + (owner != null ? owner.hashCode() : 0);
+        result = 31 * result + (disableRendering ? 1 : 0);
+        result = 31 * result + (disableRenderingMessage != null ? disableRenderingMessage.hashCode() : 0);
+        result = 31 * result + (ratings != null ? ratings.hashCode() : 0);
+        result = 31 * result + (tags != null ? tags.hashCode() : 0);
+        result = 31 * result + (categories != null ? categories.hashCode() : 0);
+        result = 31 * result + (featured ? 1 : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetRatingImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetRatingImpl.java
new file mode 100644
index 0000000..e31270a
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetRatingImpl.java
@@ -0,0 +1,77 @@
+package org.apache.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.WidgetRating;
+
+public class WidgetRatingImpl implements WidgetRating {
+
+    private Long id;
+    private Long widgetId;
+    private Long userId;
+    private Integer score;
+
+    public WidgetRatingImpl() {
+    }
+
+    public WidgetRatingImpl(long id, long widgetId, long userId, int score) {
+        this.id = id;
+        this.widgetId = widgetId;
+        this.userId = userId;
+        this.score = score;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getWidgetId() {
+        return widgetId;
+    }
+
+    public void setWidgetId(Long widgetId) {
+        this.widgetId = widgetId;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public Integer getScore() {
+        return score;
+    }
+
+    public void setScore(Integer score) {
+        this.score = score;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof WidgetRatingImpl)) return false;
+
+        WidgetRatingImpl that = (WidgetRatingImpl) o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null) return false;
+        if (score != null ? !score.equals(that.score) : that.score != null) return false;
+        if (userId != null ? !userId.equals(that.userId) : that.userId != null) return false;
+        if (widgetId != null ? !widgetId.equals(that.widgetId) : that.widgetId != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (widgetId != null ? widgetId.hashCode() : 0);
+        result = 31 * result + (userId != null ? userId.hashCode() : 0);
+        result = 31 * result + (score != null ? score.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetTagImpl.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetTagImpl.java
new file mode 100644
index 0000000..f99dae9
--- /dev/null
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/impl/WidgetTagImpl.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * 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.rave.portal.model.impl;
+
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.Tag;
+import org.apache.rave.portal.model.WidgetTag;
+
+import java.util.Date;
+
+public class WidgetTagImpl implements WidgetTag {
+
+    private Long widgetId;
+    private User user;
+    private Tag tag;
+    private Date createdDate;
+
+    public WidgetTagImpl() {
+    }
+
+    public WidgetTagImpl(Long widgetId, User user, Date createdDate, Tag tag) {
+        this.widgetId = widgetId;
+        this.user = user;
+        this.tag = tag;
+        this.createdDate = createdDate;
+    }
+
+    @Override
+    public Long getWidgetId() {
+        return this.widgetId;
+    }
+
+    @Override
+    public void setWidgetId(Long id) {
+        this.widgetId = id;
+    }
+
+    @Override
+    public User getUser() {
+        return this.user;
+    }
+
+    @Override
+    public void setUser(User user) {
+        this.user = user;
+    }
+
+    @Override
+    public Tag getTag() {
+        return this.tag;
+    }
+
+    @Override
+    public void setTag(Tag tag) {
+        this.tag = tag;
+    }
+
+    @Override
+    public Date getCreatedDate() {
+       return this.createdDate;
+    }
+
+    @Override
+    public void setCreatedDate(Date date) {
+        this.createdDate = date;
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/util/SearchResult.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/util/SearchResult.java
index ddad2a7..8ed28d6 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/util/SearchResult.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/util/SearchResult.java
@@ -19,14 +19,12 @@
 
 package org.apache.rave.portal.model.util;
 
-import org.apache.rave.persistence.BasicEntity;
-
 import java.util.List;
 
 /**
  * Wrapper for search results.
  */
-public class SearchResult<T extends BasicEntity> {
+public class SearchResult<T> {
     private List<T> resultSet;
     private int pageSize;
     private int offset;
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/ApplicationDataRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/ApplicationDataRepository.java
similarity index 93%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/ApplicationDataRepository.java
rename to rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/ApplicationDataRepository.java
index 5f4cc95..a8e127f 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/ApplicationDataRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/ApplicationDataRepository.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations

  * under the License.

  */

-package org.apache.rave.opensocial.repository;

+package org.apache.rave.portal.repository;

 

-import org.apache.rave.opensocial.model.ApplicationData;

+import org.apache.rave.portal.model.ApplicationData;

 import org.apache.rave.persistence.Repository;

 

 import java.util.List;

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/AuthorityRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/AuthorityRepository.java
index d3ab111..ab300b0 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/AuthorityRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/AuthorityRepository.java
@@ -30,7 +30,7 @@
 public interface AuthorityRepository extends Repository<Authority> {
 
     /**
-     * Finds the {@link Authority} by its name
+     * Finds the {@link org.apache.rave.portal.model.Authority} by its name
      *
      * @param authorityName (unique) name of the Authority
      * @return Authority if it can be found, otherwise {@literal null}
@@ -38,12 +38,12 @@
     Authority getByAuthority(String authorityName);
 
     /**
-     * @return a List of all {@link Authority}'s.
+     * @return a List of all {@link org.apache.rave.portal.model.Authority}'s.
      */
     List<Authority> getAll();
-    
+
     /**
-     * @return a List of all default {@link Authority}'s.
+     * @return a List of all default {@link org.apache.rave.portal.model.Authority}'s.
      */
     List<Authority> getAllDefault();
 
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/OAuthConsumerStoreRepository.java
similarity index 73%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java
rename to rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/OAuthConsumerStoreRepository.java
index c198de5..48e6a0c 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/OAuthConsumerStoreRepository.java
@@ -17,22 +17,22 @@
  * under the License.
  */
 
-package org.apache.rave.gadgets.oauth.repository;
+package org.apache.rave.portal.repository;
 
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.portal.model.OAuthConsumerStore;
 import org.apache.rave.persistence.Repository;
 
 /**
- * Repository interface for {@link OAuthConsumerStore}
+ * Repository interface for {@link org.apache.rave.portal.model.OAuthConsumerStore}
  */
 public interface OAuthConsumerStoreRepository extends Repository<OAuthConsumerStore> {
 
     /**
-     * Fetches {@link OAuthConsumerStore} based on the gadget location and the service provider
+     * Fetches {@link org.apache.rave.portal.model.OAuthConsumerStore} based on the gadget location and the service provider
      *
      * @param gadgetUri   location of the gadget definition
      * @param serviceName name of the service provider
-     * @return {@link OAuthConsumerStore} or {@literal null} if none matches the criteria
+     * @return {@link org.apache.rave.portal.model.OAuthConsumerStore} or {@literal null} if none matches the criteria
      */
     OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName);
 }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/OAuthTokenInfoRepository.java
similarity index 79%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java
rename to rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/OAuthTokenInfoRepository.java
index 5e46553..77f370f 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/OAuthTokenInfoRepository.java
@@ -17,25 +17,25 @@
  * under the License.
  */
 
-package org.apache.rave.gadgets.oauth.repository;
+package org.apache.rave.portal.repository;
 
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.portal.model.OAuthTokenInfo;
 import org.apache.rave.persistence.Repository;
 
 /**
- * Interface for handling {@link OAuthTokenInfo} queries
+ * Interface for handling {@link org.apache.rave.portal.model.OAuthTokenInfo} queries
  */
 public interface OAuthTokenInfoRepository extends Repository<OAuthTokenInfo> {
 
     /**
-     * Retrieves {@link OAuthTokenInfo}
+     * Retrieves {@link org.apache.rave.portal.model.OAuthTokenInfo}
      *
      * @param userId      unique identifier of gadget viewer
      * @param appUrl      URL of the gadget
      * @param moduleId    the module ID of the application
      * @param tokenName   gadget's nickname for the token to use
      * @param serviceName name of the service provider
-     * @return {@link OAuthTokenInfo} or {@literal null} if none matches the criteria
+     * @return {@link org.apache.rave.portal.model.OAuthTokenInfo} or {@literal null} if none matches the criteria
      */
     OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
                                              String tokenName, String serviceName);
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PageRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PageRepository.java
index 76297f8..a00d8d6 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PageRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PageRepository.java
@@ -19,11 +19,7 @@
 package org.apache.rave.portal.repository;

 

 import org.apache.rave.persistence.Repository;

-import org.apache.rave.portal.model.Page;

-import org.apache.rave.portal.model.PageTemplate;

-import org.apache.rave.portal.model.PageType;

-import org.apache.rave.portal.model.PageUser;

-import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.*;

 

 import java.util.List;

 

@@ -65,14 +61,14 @@
     boolean hasPersonPage(long userId);

 

     /**

-     * Returns a list of pageUser records of a certain pageType.  

-     * Used to get a list of a users pages(user) with render sequencing. 

+     * Returns a list of pageUser records of a certain pageType.

+     * Used to get a list of a users pages(user) with render sequencing.

      * @param userId

      * @param pageType

      * @return a list of pageUser

      */

     public List<PageUser> getPagesForUser(Long userId, PageType pageType);

-    

+

 

     /**

      * Returns a single pageUser tuple based on userId and pageId

diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/PersonRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PersonRepository.java
similarity index 72%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/PersonRepository.java
rename to rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PersonRepository.java
index 7fbad2e..69638cf 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/PersonRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PersonRepository.java
@@ -17,12 +17,10 @@
  * under the License.
  */
 
-package org.apache.rave.opensocial.repository;
+package org.apache.rave.portal.repository;
 
-import org.apache.rave.portal.model.Person;
 import org.apache.rave.persistence.Repository;
-import org.apache.shindig.protocol.model.FilterOperation;
-import org.apache.shindig.social.opensocial.spi.CollectionOptions;
+import org.apache.rave.portal.model.Person;
 
 import java.util.List;
 
@@ -53,17 +51,6 @@
     List<Person> findAllConnectedPeople(String username, String appId);
 
     /**
-     * Gets all people connected to the given user including friends, fellow group members, etc, filtered by the specified field
-     *
-     * @param username the username of the person to query for
-     * @param field the field to filter on
-     * @param operation the type of filter to apply
-     * @param value the value of the specified filter
-     * @return a filtered list of connected individuals
-     */
-    List<Person> findAllConnectedPeople(String username, String field, FilterOperation operation, String value);
-
-    /**
      * Finds a list of all people connected to the given person who are friends with the second user
      * @param username the user to find connected individuals for
      * @param friendUsername the username of the person to filter connections by
@@ -88,17 +75,6 @@
     List<Person> findFriends(String username, String appId);
 
     /**
-     * Finds the list of friends for the given person, filtered by the specified field
-     *
-     * @param username the username of the user to find friends for
-     * @param field the field to filter on
-     * @param operation the type of filter to apply
-     * @param value the value of the specified filter
-     * @return a filtered list of friends
-     */
-    List<Person> findFriends(String username, String field, FilterOperation operation, String value);
-
-    /**
      * Finds the list of friends for the user who are also friends of the given person
      *
      * @param username the username of the user to find friends for
@@ -124,17 +100,6 @@
     List<Person> findByGroup(String groupId, String appId);
 
     /**
-     * Finds a subset of people in the specified group filtered by the specified field
-     *
-     * @param groupId the Id of the group to query
-     * @param field the field to filter on
-     * @param operation the type of filter to apply
-     * @param value the value of the specified filter
-     * @return a filtered list of group members
-     */
-    List<Person> findByGroup(String groupId, String field, FilterOperation operation, String value);
-
-    /**
      * Finds a subset of people in teh specified group who have the given friend
      *
      * @param groupId the Id of the group to query
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PortalPreferenceRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PortalPreferenceRepository.java
index 76527ff..8231b55 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PortalPreferenceRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/PortalPreferenceRepository.java
@@ -25,7 +25,7 @@
 import java.util.List;
 
 /**
- * Provides persistence operations for the {@link PortalPreference}
+ * Provides persistence operations for the {@link org.apache.rave.portal.model.PortalPreference}
  */
 public interface PortalPreferenceRepository extends Repository<PortalPreference> {
 
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/TagRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/TagRepository.java
index 5afd0f3..125264f 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/TagRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/TagRepository.java
@@ -29,7 +29,7 @@
  */

 public interface TagRepository extends Repository<Tag> {

     /**

-     * @return a List of all {@link Tag}'s.

+     * @return a List of all {@link org.apache.rave.portal.model.Tag}'s.

      */

 

     List<Tag> getAll();

@@ -47,7 +47,7 @@
     Tag getByKeyword(String keyword);

 

     /**

-     * @return a List of all tag not link to this widget{@link Tag}'s.

+     * @return a List of all tag not link to this widget{@link org.apache.rave.portal.model.Tag}'s.

      */

 

     List<Tag> getAvailableTagsByWidgetId(Long widgetId);

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/UserRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/UserRepository.java
index ba49eef..8672764 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/UserRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/UserRepository.java
@@ -21,29 +21,28 @@
 import org.apache.rave.persistence.Repository;

 import org.apache.rave.portal.model.User;

 

-import java.util.Date;

 import java.util.List;

 

 public interface UserRepository extends Repository<User> {

 

     /**

-     * Gets a {@link User} by its username

+     * Gets a {@link org.apache.rave.portal.model.User} by its username

      *

      * @param username the (unique) name of the user

-     * @return {@link User} if one exists, otherwise {@literal null}

+     * @return {@link org.apache.rave.portal.model.User} if one exists, otherwise {@literal null}

      */

     User getByUsername(String username);

 

     /**

-     * Gets a {@link User} by its email address

+     * Gets a {@link org.apache.rave.portal.model.User} by its email address

      *

      * @param userEmail the (unique) email address of the user

-     * @return {@link User} if one exists, otherwise {@literal null}

+     * @return {@link org.apache.rave.portal.model.User} if one exists, otherwise {@literal null}

      */

     User getByUserEmail(String userEmail);

 

     /**

-     * List of {@link User}'s with a limited resultset

+     * List of {@link org.apache.rave.portal.model.User}'s with a limited resultset

      *

      * @param offset   start point within the total resultset

      * @param pageSize maximum number of items to be returned (for paging)

@@ -52,12 +51,12 @@
     List<User> getLimitedList(int offset, int pageSize);

 

     /**

-     * @return the total number of {@link User}'s in the repository. Useful for paging.

+     * @return the total number of {@link org.apache.rave.portal.model.User}'s in the repository. Useful for paging.

      */

     int getCountAll();

 

     /**

-     * List of {@link User}'s that match a searchterm in their username or email address

+     * List of {@link org.apache.rave.portal.model.User}'s that match a searchterm in their username or email address

      *

      * @param searchTerm search term

      * @param offset     start point within the total resultset

@@ -69,7 +68,7 @@
     /**

      *

      * @param searchTerm search term

-     * @return the total number of {@link User}'s that match a searchterm in their username or email address.

+     * @return the total number of {@link org.apache.rave.portal.model.User}'s that match a searchterm in their username or email address.

      *         Useful for paging.

      */

     int getCountByUsernameOrEmail(String searchTerm);

@@ -83,10 +82,10 @@
     List<User> getAllByAddedWidget(long widgetId);

 

     /**

-     * Gets a {@link User} by generated forgot email hash

+     * Gets a {@link org.apache.rave.portal.model.User} by generated forgot email hash

      *

      * @param hash unique generated hash

-     * @return {@link User} if one exists for given hash, otherwise {@literal null}

+     * @return {@link org.apache.rave.portal.model.User} if one exists for given hash, otherwise {@literal null}

      */

     User getByForgotPasswordHash(String hash);

 

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRatingRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRatingRepository.java
index 84d83d0..4c8791b 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRatingRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRatingRepository.java
@@ -25,11 +25,11 @@
 public interface WidgetRatingRepository extends Repository<WidgetRating> {
 
     /**
-     * Tries to find a {@link WidgetRating} by the id's of a Widget and USer
+     * Tries to find a {@link org.apache.rave.portal.model.WidgetRating} by the id's of a Widget and USer
      *
      * @param widgetId unique identifier of a Widget
      * @param userId   unique identifier of a User
-     * @return {@link WidgetRating} if it exists, otherwise {@literal null}
+     * @return {@link org.apache.rave.portal.model.WidgetRating} if it exists, otherwise {@literal null}
      */
     WidgetRating getByWidgetIdAndUserId(Long widgetId, Long userId);
 
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java
index 938ae46..c9d26c7 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetRepository.java
@@ -124,10 +124,10 @@
      * @return {@link Widget} if it can be found, otherwise {@literal null}

      */

     Widget getByUrl(String widgetUrl);

-    

+

     /**

      * Generates the widget statistics for a gadget including the user's specific information.

-     * 

+     *

      * @param widget_id id of the widget

      * @param user_id id of the user

      * @return {@link WidgetStatistics} with the rating information

@@ -146,7 +146,7 @@
      * Generates the mapping of widget ratings for the user.

      *

      * @param userId id of the user

-     * @return Mapping of {@link WidgetRating} objects keyed off of the widget's entityId

+     * @return Mapping of {@link org.apache.rave.portal.model.WidgetRating} objects keyed off of the widget's entityId

      */

     Map<Long, WidgetRating> getUsersWidgetRatings(long userId);

 

@@ -159,7 +159,7 @@
      * @return valid list of widgets, can be empty

      */

      List<Widget> getWidgetsByTag(String tagKeyWord, int offset, int pageSize);

- 

+

     /**

      * Counts the total number of {@link Widget}'s that match tag keyword. Useful for paging.

      *

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetTagRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetTagRepository.java
index 87269a5..6b5fe58 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetTagRepository.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/WidgetTagRepository.java
@@ -24,11 +24,11 @@
 public interface WidgetTagRepository extends Repository<WidgetTag> {

 

     /**

-         * Tries to find a {@link WidgetTag} by the id's of a Widget and Tag keyword

+         * Tries to find a {@link org.apache.rave.portal.model.WidgetTag} by the id's of a Widget and Tag keyword

          *

          * @param widgetId unique identifier of a Widget

          * @param keyword   tag's keyword

-         * @return {@link WidgetTag} if it exists, otherwise {@literal null}

+         * @return {@link org.apache.rave.portal.model.WidgetTag} if it exists, otherwise {@literal null}

          */

         WidgetTag getByWidgetIdAndTag(Long widgetId, String keyword);

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepository.java
deleted file mode 100644
index a7b79e6..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepository.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.repository.impl;
-
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.portal.model.Authority;
-import org.apache.rave.portal.repository.AuthorityRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-/**
- * JPA implementation for {@link org.apache.rave.portal.repository.AuthorityRepository}
- */
-@Repository
-public class JpaAuthorityRepository extends AbstractJpaRepository<Authority>
-        implements AuthorityRepository {
-
-    public JpaAuthorityRepository() {
-        super(Authority.class);
-    }
-
-    @Override
-    public Authority getByAuthority(String authorityName) {
-        TypedQuery<Authority> query = manager.createNamedQuery(Authority.GET_BY_AUTHORITY_NAME, Authority.class);
-        query.setParameter(Authority.PARAM_AUTHORITY_NAME, authorityName);
-        return getSingleResult(query.getResultList());
-    }
-
-    @Override
-    public List<Authority> getAll() {
-        TypedQuery<Authority> query = manager.createNamedQuery(Authority.GET_ALL, Authority.class);
-        return query.getResultList();
-    }
-    
-    @Override
-    public List<Authority> getAllDefault() {
-        TypedQuery<Authority> query = manager.createNamedQuery(Authority.GET_ALL_DEFAULT, Authority.class);
-        return query.getResultList();
-    }    
-
-    @Override
-    public int getCountAll() {
-        Query query = manager.createNamedQuery(Authority.COUNT_ALL);
-        Number countResult = (Number) query.getSingleResult();
-        return countResult.intValue();
-    }
-}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaCategoryRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaCategoryRepository.java
deleted file mode 100644
index 1754f73..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaCategoryRepository.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.repository.impl;

-

-import org.apache.rave.persistence.jpa.AbstractJpaRepository;

-import org.apache.rave.portal.model.Category;

-import org.apache.rave.portal.model.User;

-import org.apache.rave.portal.repository.CategoryRepository;

-import org.springframework.stereotype.Repository;

-

-import java.util.List;

-

-/**

- * JPA implementation for {@link org.apache.rave.portal.repository.CategoryRepository}

- */

-@Repository

-public class JpaCategoryRepository extends AbstractJpaRepository<Category> implements CategoryRepository {

-

-    public JpaCategoryRepository() {

-        super(Category.class);

-    }

-

-    @Override

-    public List<Category> getAll() {

-        return manager.createNamedQuery(Category.GET_ALL, Category.class).getResultList();

-    }

-

-    @Override

-    public int removeFromCreatedOrModifiedFields(long userId) {

-        List<Category> categories = getAll();

-        int numRecordsChanged = 0;

-        for (Category category : categories) {

-            boolean changed = false;

-            User createdUser = category.getCreatedUser();

-            User lastModifiedUser = category.getLastModifiedUser();

-            if (createdUser != null && userId == createdUser.getEntityId()) {

-                category.setCreatedUser(null);

-                changed = true;

-            }

-            if (lastModifiedUser != null && userId == lastModifiedUser.getEntityId()) {

-                category.setLastModifiedUser(null);

-                changed = true;

-            }

-            if (changed) {

-                numRecordsChanged++;

-                save(category);

-            }

-        }

-        return numRecordsChanged;

-    }

-}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepository.java
deleted file mode 100644
index 2a14472..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepository.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.repository.impl;
-
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.portal.model.PageLayout;
-import org.apache.rave.portal.repository.PageLayoutRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.TypedQuery;
-
-import java.util.List;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-
-/**
- */
-@Repository
-public class JpaPageLayoutRepository extends AbstractJpaRepository<PageLayout> implements PageLayoutRepository{
-
-    public JpaPageLayoutRepository() {
-        super(PageLayout.class);
-    }
-
-    @Override
-    public PageLayout getByPageLayoutCode(String codename){
-        TypedQuery<PageLayout>query = manager.createNamedQuery(PageLayout.PAGELAYOUT_GET_BY_LAYOUT_CODE,PageLayout.class);
-        query.setParameter("code",codename);
-        return getSingleResult(query.getResultList());
-    }
-
-    @Override
-    public List<PageLayout> getAll() {
-        return manager.createNamedQuery(PageLayout.PAGELAYOUT_GET_ALL, PageLayout.class).getResultList();
-    }
-
-    @Override
-    public List<PageLayout> getAllUserSelectable() {
-        return manager.createNamedQuery(PageLayout.PAGELAYOUT_GET_ALL_USER_SELECTABLE, PageLayout.class).getResultList();
-    }
-}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepository.java
deleted file mode 100644
index 1d7fe9a..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepository.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.repository.impl;
-
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.portal.model.PortalPreference;
-import org.apache.rave.portal.repository.PortalPreferenceRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-/**
- * JPA implementation for {@link PortalPreferenceRepository}
- */
-@Repository
-public class JpaPortalPreferenceRepository extends AbstractJpaRepository<PortalPreference> implements PortalPreferenceRepository {
-
-    public JpaPortalPreferenceRepository() {
-        super(PortalPreference.class);
-    }
-
-    @Override
-    public List<PortalPreference> getAll() {
-        final TypedQuery<PortalPreference> query =
-                manager.createNamedQuery(PortalPreference.GET_ALL, PortalPreference.class);
-        return query.getResultList();
-    }
-
-    @Override
-    public PortalPreference getByKey(String key) {
-        final TypedQuery<PortalPreference> query =
-                manager.createNamedQuery(PortalPreference.GET_BY_KEY, PortalPreference.class);
-        query.setParameter(PortalPreference.PARAM_KEY, key);
-        return getSingleResult(query.getResultList());
-    }
-}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionRepository.java
deleted file mode 100644
index 2f29244..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionRepository.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.repository.impl;
-
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.portal.model.Region;
-import org.apache.rave.portal.repository.RegionRepository;
-import org.springframework.stereotype.Repository;
-
-
-@Repository
-public class JpaRegionRepository extends AbstractJpaRepository<Region> implements RegionRepository {
-  public JpaRegionRepository() {
-      super(Region.class);
-  }
-}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepository.java
deleted file mode 100644
index 11eaad4..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepository.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.repository.impl;

-

-import org.apache.rave.persistence.jpa.AbstractJpaRepository;

-import org.apache.rave.portal.model.RegionWidget;

-import org.apache.rave.portal.repository.RegionWidgetRepository;

-import org.springframework.stereotype.Repository;

-

-

-@Repository

-public class JpaRegionWidgetRepository extends AbstractJpaRepository<RegionWidget> implements RegionWidgetRepository {

-    public JpaRegionWidgetRepository() {

-        super(RegionWidget.class);

-    }

-}
\ No newline at end of file
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaTagRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaTagRepository.java
deleted file mode 100644
index db87acf..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaTagRepository.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.repository.impl;

-

-import org.apache.rave.persistence.jpa.AbstractJpaRepository;

-import org.apache.rave.portal.model.Tag;

-import org.apache.rave.portal.repository.TagRepository;

-import org.springframework.stereotype.Repository;

-

-import javax.persistence.Query;

-import javax.persistence.TypedQuery;

-import java.util.List;

-

-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;

-

-/**

- * JPA implementation for {@link org.apache.rave.portal.repository.AuthorityRepository}

- */

-@Repository

-public class JpaTagRepository extends AbstractJpaRepository<Tag>

-        implements TagRepository {

-

-    public JpaTagRepository() {

-        super(Tag.class);

-    }

-

-

-    @Override

-    public List<Tag> getAll() {

-        TypedQuery<Tag> query = manager.createNamedQuery(Tag.GET_ALL, Tag.class);

-        return query.getResultList();

-    }

-

-

-    @Override

-    public int getCountAll() {

-        Query query = manager.createNamedQuery(Tag.COUNT_ALL);

-        Number countResult = (Number) query.getSingleResult();

-        return countResult.intValue();

-    }

-

-    @Override

-    public Tag getByKeyword(String keyword) {

-        if (keyword != null) {

-            keyword = keyword.trim();

-        }

-        TypedQuery<Tag> query = manager.createNamedQuery(Tag.FIND_BY_KEYWORD, Tag.class);

-        query.setParameter("keyword", keyword);

-        return getSingleResult(query.getResultList());

-    }

-

-    @Override

-    public List<Tag> getAvailableTagsByWidgetId(Long widgetId) {

-        TypedQuery<Tag> query = manager.createNamedQuery(Tag.GET_ALL_NOT_IN_WIDGET, Tag.class);

-        query.setParameter("widgetId", widgetId);

-        return query.getResultList();

-    }

-

-}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaUserRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaUserRepository.java
deleted file mode 100644
index 5fc428e..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaUserRepository.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.repository.impl;
-
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.portal.model.Page;
-import org.apache.rave.portal.model.User;
-import org.apache.rave.portal.model.WidgetComment;
-import org.apache.rave.portal.model.WidgetRating;
-import org.apache.rave.portal.repository.UserRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
-
-import java.util.Date;
-import java.util.List;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getPagedResultList;
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-/**
- */
-@Repository
-public class JpaUserRepository extends AbstractJpaRepository<User> implements UserRepository {
-
-    public JpaUserRepository() {
-        super(User.class);
-    }
-
-    @Override
-    public User getByUsername(String username) {
-        TypedQuery<User> query = manager.createNamedQuery(User.USER_GET_BY_USERNAME, User.class);
-        query.setParameter(User.PARAM_USERNAME, username);
-        return getSingleResult(query.getResultList());
-    }
-
-    @Override
-    public User getByUserEmail(String userEmail) {
-        TypedQuery<User> query = manager.createNamedQuery(User.USER_GET_BY_USER_EMAIL, User.class);
-        query.setParameter(User.PARAM_EMAIL, userEmail);
-        return getSingleResult(query.getResultList());
-    }
-
-    @Override
-    public List<User> getLimitedList(int offset, int pageSize) {
-        TypedQuery<User> query = manager.createNamedQuery(User.USER_GET_ALL, User.class);
-        return getPagedResultList(query, offset, pageSize);
-    }
-
-    @Override
-    public int getCountAll() {
-        Query query = manager.createNamedQuery(User.USER_COUNT_ALL);
-        Number countResult = (Number) query.getSingleResult();
-        return countResult.intValue();
-    }
-
-    @Override
-    public List<User> findByUsernameOrEmail(String searchTerm, int offset, int pageSize) {
-        TypedQuery<User> query = manager.createNamedQuery(User.USER_FIND_BY_USERNAME_OR_EMAIL, User.class);
-        query.setParameter(User.PARAM_SEARCHTERM, "%" + searchTerm.toLowerCase() + "%");
-        return getPagedResultList(query, offset, pageSize);
-    }
-
-    @Override
-    public int getCountByUsernameOrEmail(String searchTerm) {
-        Query query = manager.createNamedQuery(User.USER_COUNT_FIND_BY_USERNAME_OR_EMAIL);
-        query.setParameter(User.PARAM_SEARCHTERM, "%" + searchTerm.toLowerCase() + "%");
-        Number countResult = (Number) query.getSingleResult();
-        return countResult.intValue();
-    }
-
-    @Override
-    public List<User> getAllByAddedWidget(long widgetId) {
-        TypedQuery<User> query = manager.createNamedQuery(User.USER_GET_ALL_FOR_ADDED_WIDGET, User.class);
-        query.setParameter(User.PARAM_WIDGET_ID, widgetId);
-        return query.getResultList();
-    }
-
-    @Override
-    public User getByForgotPasswordHash(String hash) {
-        TypedQuery<User> query = manager.createNamedQuery(User.USER_GET_BY_FORGOT_PASSWORD_HASH, User.class);
-        query.setParameter(User.PARAM_FORGOT_PASSWORD_HASH, hash);
-        return getSingleResult(query.getResultList());
-    }
-
-}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepository.java
deleted file mode 100644
index 9412584..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepository.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2011 The Apache Software Foundation.
- *
- * 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.rave.portal.repository.impl;
-
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.portal.model.WidgetComment;
-import org.apache.rave.portal.repository.WidgetCommentRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.TypedQuery;
-
-@Repository
-public class JpaWidgetCommentRepository extends AbstractJpaRepository<WidgetComment> implements WidgetCommentRepository {
-    
-    public JpaWidgetCommentRepository() {
-        super(WidgetComment.class);
-    }
-
-    @Override
-    public int deleteAll(Long userId) {
-        TypedQuery<WidgetComment> query = manager.createNamedQuery(WidgetComment.DELETE_ALL_BY_USER, WidgetComment.class);
-        query.setParameter("userId", userId);
-        return query.executeUpdate();
-    }
-}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepository.java
deleted file mode 100644
index 3bf407e..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepository.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.repository.impl;
-
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.portal.model.WidgetRating;
-import org.apache.rave.portal.repository.WidgetRatingRepository;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.TypedQuery;
-import java.util.List;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-/**
- * JPA implementation for {@link org.apache.rave.portal.repository.WidgetRatingRepository}
- */
-@Repository
-public class JpaWidgetRatingRepository extends AbstractJpaRepository<WidgetRating> implements WidgetRatingRepository {
-
-    public JpaWidgetRatingRepository() {
-        super(WidgetRating.class);
-    }
-
-    @Override
-    public WidgetRating getByWidgetIdAndUserId(Long widgetId, Long userId) {
-        TypedQuery<WidgetRating> query =
-                manager.createNamedQuery(WidgetRating.WIDGET_RATING_BY_WIDGET_AND_USER, WidgetRating.class);
-        query.setParameter(WidgetRating.PARAM_WIDGET_ID, widgetId);
-        query.setParameter(WidgetRating.PARAM_USER_ID, userId);
-        final List<WidgetRating> resultList = query.getResultList();
-        return getSingleResult(resultList);
-    }
-
-    @Override
-    public int deleteAll(Long userId) {
-        TypedQuery<WidgetRating> query = manager.createNamedQuery(WidgetRating.DELETE_ALL_BY_USER, WidgetRating.class);
-        query.setParameter("userId", userId);
-        return query.executeUpdate();
-    }
-}
\ No newline at end of file
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepository.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepository.java
deleted file mode 100644
index e306f7a..0000000
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepository.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*

- * Copyright 2011 The Apache Software Foundation.

- *

- * 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.rave.portal.repository.impl;

-

-import org.apache.rave.persistence.jpa.AbstractJpaRepository;

-import org.apache.rave.portal.model.WidgetTag;

-import org.apache.rave.portal.repository.WidgetTagRepository;

-import org.springframework.stereotype.Repository;

-

-import javax.persistence.TypedQuery;

-

-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;

-

-@Repository

-public class JpaWidgetTagRepository extends AbstractJpaRepository<WidgetTag> implements WidgetTagRepository {

-

-    JpaWidgetTagRepository() {

-        super(WidgetTag.class);

-    }

-

-    @Override

-    public WidgetTag getByWidgetIdAndTag(Long widgetId, String keyword) {

-        if (keyword != null) {

-            keyword = keyword.trim();

-        }

-        TypedQuery<WidgetTag> query = manager.createNamedQuery(WidgetTag.FIND_BY_WIDGET_AND_KEYWORD, WidgetTag.class);

-        query.setParameter("keyword", keyword);

-        query.setParameter("widgetId", widgetId);

-        return getSingleResult(query.getResultList());

-    }

-

-

-}

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluator.java
index f8c848a..ae6efd2 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluator.java
@@ -43,19 +43,19 @@
     public DefaultCategoryPermissionEvaluator(CategoryRepository categoryRepository) {
         this.categoryRepository = categoryRepository;
     }
-   
+
     @Override
     public Class<Category> getType() {
         return Category.class;
     }
-    
+
     /**
      * Checks to see if the Authentication object has the supplied Permission
      * on the supplied Category object.  This method invokes the private hasPermission
      * function with the trustedDomainObject parameter set to false since we don't
-     * know if the model being passed in was modified in any way from the 
+     * know if the model being passed in was modified in any way from the
      * actual entity in the database.
-     * 
+     *
      * @param authentication the current Authentication object
      * @param category the Category model object
      * @param permission the Permission to check
@@ -64,16 +64,16 @@
     @Override
     public boolean hasPermission(Authentication authentication, Category category, Permission permission) {
         return hasPermission(authentication, category, permission, false);
-    }    
+    }
 
     /**
-     * Checks to see if the Authentication object has the supplied Permission 
+     * Checks to see if the Authentication object has the supplied Permission
      * for the Entity represented by the targetId(entityId) and targetType(model class name).
-     * This method invokes the private hasPermission function with the 
+     * This method invokes the private hasPermission function with the
      * trustedDomainObject parameter set to true since we must pull the entity
      * from the database and are guaranteed a trusted domain object,
      * before performing our permission checks.
-     * 
+     *
      * @param authentication the current Authentication object
      * @param targetId the entityId of the model to check, or a RaveSecurityContext object
      * @param targetType the class of the model to check
@@ -84,27 +84,27 @@
     public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Permission permission) {
         boolean hasPermission = false;
         if (targetId instanceof RaveSecurityContext) {
-            hasPermission = verifyRaveSecurityContext(authentication, (RaveSecurityContext)targetId);           
+            hasPermission = verifyRaveSecurityContext(authentication, (RaveSecurityContext)targetId);
         } else {
             hasPermission = hasPermission(authentication, categoryRepository.get((Long)targetId), permission, true);
         }
         return hasPermission;
-    }  
-        
+    }
+
     private boolean hasPermission(Authentication authentication, Category category, Permission permission, boolean trustedDomainObject) {
         // this is our container of trusted category objects that can be re-used
         // in this method so that the same trusted category object doesn't have to
         // be looked up in the repository multiple times
         List<Category> trustedCategoryContainer = new ArrayList<Category>();
-        
+
         // first execute the AbstractModelPermissionEvaluator's hasPermission function
-        // to see if it allows permission via it's "higher authority" logic                
+        // to see if it allows permission via it's "higher authority" logic
         if (super.hasPermission(authentication, category, permission)) {
             return true;
         }
-        
+
         // perform the security logic depending on the Permission type
-        boolean hasPermission = false;                       
+        boolean hasPermission = false;
         switch (permission) {
             case READ:
                 // all users can read any Category
@@ -121,10 +121,10 @@
                 log.warn("unknown permission: " + permission);
                 break;
         }
-        
+
         return hasPermission;
-    }       
-    
+    }
+
     // returns a trusted Category object, either from the CategoryRepository, or the
     // cached container list
     private Category getTrustedCategory(long categoryId, List<Category> trustedCategoryContainer) {
@@ -137,7 +137,7 @@
         }
         return p;
     }
-   
+
     // checks to see if the Authentication object principal is the owner of the supplied category object
     // if trustedDomainObject is false, pull the entity from the database first to ensure
     // the model object is trusted and hasn't been modified
@@ -146,7 +146,7 @@
         if (trustedDomainObject) {
             trustedCategory = category;
         } else {
-            trustedCategory = getTrustedCategory(category.getEntityId(), trustedCategoryContainer);
+            trustedCategory = getTrustedCategory(category.getId(), trustedCategoryContainer);
         }
 
         return isCategoryCreatedUserByUsername(authentication, trustedCategory.getCreatedUser().getUsername());
@@ -157,7 +157,7 @@
     }
 
     private boolean isCategoryCreatedUserById(Authentication authentication, Long userId) {
-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);
+        return ((User)authentication.getPrincipal()).getId().equals(userId);
     }
 
     private boolean verifyRaveSecurityContext(Authentication authentication, RaveSecurityContext raveSecurityContext) {
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluator.java
index 2284099..73fb242 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluator.java
@@ -18,10 +18,7 @@
  */
 package org.apache.rave.portal.security.impl;
 
-import org.apache.rave.portal.model.Page;
-import org.apache.rave.portal.model.PageType;
-import org.apache.rave.portal.model.PageUser;
-import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.*;
 import org.apache.rave.portal.repository.PageRepository;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,49 +32,49 @@
 
 /**
  * The default implementation of the ModelPermissionEvaluator for Page objects
- * 
+ *
  * @author carlucci
  */
 @Component
 public class DefaultPagePermissionEvaluator extends AbstractModelPermissionEvaluator<Page> {
     private Logger log = LoggerFactory.getLogger(getClass());
-    private PageRepository pageRepository;   
-    
+    private PageRepository pageRepository;
+
     @Autowired
-    public DefaultPagePermissionEvaluator(PageRepository pageRepository) {       
-        this.pageRepository = pageRepository;        
+    public DefaultPagePermissionEvaluator(PageRepository pageRepository) {
+        this.pageRepository = pageRepository;
     }
-   
+
     @Override
     public Class<Page> getType() {
         return Page.class;
     }
-    
+
     /**
      * Checks to see if the Authentication object has the supplied Permission
      * on the supplied Page object.  This method invokes the private hasPermission
      * function with the trustedDomainObject parameter set to false since we don't
-     * know if the model being passed in was modified in any way from the 
+     * know if the model being passed in was modified in any way from the
      * actual entity in the database.
-     * 
+     *
      * @param authentication the current Authentication object
      * @param page the Page model object
      * @param permission the Permission to check
      * @return true if the Authentication has the proper permission, false otherwise
      */
     @Override
-    public boolean hasPermission(Authentication authentication, Page page, Permission permission) {      
+    public boolean hasPermission(Authentication authentication, Page page, Permission permission) {
         return hasPermission(authentication, page, permission, false);
-    }    
+    }
 
     /**
-     * Checks to see if the Authentication object has the supplied Permission 
+     * Checks to see if the Authentication object has the supplied Permission
      * for the Entity represented by the targetId(entityId) and targetType(model class name).
-     * This method invokes the private hasPermission function with the 
+     * This method invokes the private hasPermission function with the
      * trustedDomainObject parameter set to true since we must pull the entity
      * from the database and are guaranteed a trusted domain object,
      * before performing our permission checks.
-     * 
+     *
      * @param authentication the current Authentication object
      * @param targetId the entityId of the model to check, or a RaveSecurityContext object
      * @param targetType the class of the model to check
@@ -88,35 +85,35 @@
     public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Permission permission) {
         boolean hasPermission = false;
         if (targetId instanceof RaveSecurityContext) {
-            hasPermission = verifyRaveSecurityContext(authentication, (RaveSecurityContext)targetId);           
+            hasPermission = verifyRaveSecurityContext(authentication, (RaveSecurityContext)targetId);
         } else {
             hasPermission = hasPermission(authentication, pageRepository.get((Long)targetId), permission, true);
         }
         return hasPermission;
-    }  
-        
-    private boolean hasPermission(Authentication authentication, Page page, Permission permission, boolean trustedDomainObject) {       
-        // this is our container of trusted page objects that can be re-used 
+    }
+
+    private boolean hasPermission(Authentication authentication, Page page, Permission permission, boolean trustedDomainObject) {
+        // this is our container of trusted page objects that can be re-used
         // in this method so that the same trusted page object doesn't have to
         // be looked up in the repository multiple times
-        List<Page> trustedPageContainer = new ArrayList<Page>();                           
-        
+        List<Page> trustedPageContainer = new ArrayList<Page>();
+
         // first execute the AbstractModelPermissionEvaluator's hasPermission function
-        // to see if it allows permission via it's "higher authority" logic                
+        // to see if it allows permission via it's "higher authority" logic
         if (super.hasPermission(authentication, page, permission)) {
             return true;
         }
-        
+
         // perform the security logic depending on the Permission type
-        boolean hasPermission = false;                       
-        switch (permission) { 
+        boolean hasPermission = false;
+        switch (permission) {
             case ADMINISTER:
-                // if you are here, you are not an administrator, so you can't administer pages              
+                // if you are here, you are not an administrator, so you can't administer pages
                 break;
-            case CREATE:                                                                          
-            case DELETE:            
+            case CREATE:
+            case DELETE:
             case UPDATE:
-                // anyone can create, delete, or update a page that they own                  
+                // anyone can create, delete, or update a page that they own
                 hasPermission = isPageOwner(authentication, page, trustedPageContainer, trustedDomainObject)
                 || isPageMember(authentication, page, trustedPageContainer, trustedDomainObject, true);
                 break;
@@ -129,45 +126,45 @@
                 log.warn("unknown permission: " + permission);
                 break;
         }
-        
+
         return hasPermission;
-    }       
-    
+    }
+
     // returns a trusted Page object, either from the PageRepository, or the
     // cached container list
-    private Page getTrustedPage(long pageId, List<Page> trustedPageContainer) {       
+    private Page getTrustedPage(long pageId, List<Page> trustedPageContainer) {
         Page p = null;
-        if (trustedPageContainer.isEmpty()) {           
+        if (trustedPageContainer.isEmpty()) {
             p = pageRepository.get(pageId);
             trustedPageContainer.add(p);
         } else {
             p = trustedPageContainer.get(0);
         }
-        return p;       
-    }     
-   
-    // checks to see if the Authentication object principal is the owner of the supplied page object 
+        return p;
+    }
+
+    // checks to see if the Authentication object principal is the owner of the supplied page object
     // if trustedDomainObject is false, pull the entity from the database first to ensure
     // the model object is trusted and hasn't been modified
-    private boolean isPageOwner(Authentication authentication, Page page, List<Page> trustedPageContainer, boolean trustedDomainObject) {        
+    private boolean isPageOwner(Authentication authentication, Page page, List<Page> trustedPageContainer, boolean trustedDomainObject) {
         Page trustedPage = null;
         if (trustedDomainObject) {
             trustedPage = page;
         } else {
-            trustedPage = getTrustedPage(page.getEntityId(), trustedPageContainer);
-        }                  
-        
+            trustedPage = getTrustedPage(page.getId(), trustedPageContainer);
+        }
+
         return isPageOwnerByUsername(authentication, trustedPage.getOwner().getUsername());
-    }             
+    }
 
     private boolean isPageOwnerByUsername(Authentication authentication, String username) {
         return ((User)authentication.getPrincipal()).getUsername().equals(username);
     }
-    
+
     private boolean isPageOwnerById(Authentication authentication, Long userId) {
-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);
-    }    
-    
+        return ((User)authentication.getPrincipal()).getId().equals(userId);
+    }
+
     private boolean verifyRaveSecurityContext(Authentication authentication, RaveSecurityContext raveSecurityContext) {
         Class<?> clazz = null;
         try {
@@ -190,14 +187,14 @@
                isPageOwner(authentication, page, trustedPageContainer, trustedDomainObject) ||
                isPageMember(authentication, page, trustedPageContainer, trustedDomainObject, false);
     }
-    
+
     private boolean isPersonProfilePageOrSubPage(Page page) {
         PageType pageType = page.getPageType();
         PageType parentPageType = (page.getParentPage() == null) ? null : page.getParentPage().getPageType();
         return PageType.PERSON_PROFILE.equals(pageType) || PageType.PERSON_PROFILE.equals(parentPageType);
-    }  
-    
-    // checks to see if the Authentication object principal is a member of the supplied page object 
+    }
+
+    // checks to see if the Authentication object principal is a member of the supplied page object
     // if trustedDomainObject is false, pull the entity from the database first to ensure
     // the model object is trusted and hasn't been modified
     private boolean isPageMember(Authentication authentication, Page page, List<Page> trustedPageContainer, boolean trustedDomainObject, boolean checkEditorStatus) {
@@ -205,7 +202,7 @@
         if (trustedDomainObject) {
             trustedPage = page;
         } else {
-            trustedPage = getTrustedPage(page.getEntityId(), trustedPageContainer);
+            trustedPage = getTrustedPage(page.getId(), trustedPageContainer);
         }
         //
         // If the page has no members, there can be no member access
@@ -217,17 +214,20 @@
         // Check that the viewer is a member
         //
         String viewer = ((User)authentication.getPrincipal()).getUsername();
-        for (PageUser pageUser:trustedPage.getMembers()){
-            if (pageUser.getUser().getUsername().equals(viewer)){
-                log.info("User "+viewer+" is a member of page "+trustedPage.getEntityId());
-                if(checkEditorStatus){
-                    log.info("checking editor:"+trustedPage.getEntityId()+"@"+viewer+"@"+pageUser.isEditor());
-                    return pageUser.isEditor();
+        List<PageUser> members = trustedPage.getMembers();
+        if (members != null) {
+            for (PageUser pageUser : members){
+                if (pageUser.getUser().getUsername().equals(viewer)){
+                    log.info("User "+viewer+" is a member of page "+trustedPage.getId());
+                    if(checkEditorStatus){
+                        log.info("checking editor:"+trustedPage.getId()+"@"+viewer+"@"+pageUser.isEditor());
+                        return pageUser.isEditor();
+                    }
+                    return true;
                 }
-                return true;
             }
         }
-        log.info("User "+viewer+" is NOT a member of page "+trustedPage.getEntityId());
+        log.info("User "+viewer+" is NOT a member of page "+trustedPage.getId());
         return false;
     }
 
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluator.java
index a09f01e..165aea8 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluator.java
@@ -18,11 +18,7 @@
  */

 package org.apache.rave.portal.security.impl;

 

-import org.apache.rave.portal.model.Page;

-import org.apache.rave.portal.model.PageUser;

-import org.apache.rave.portal.model.Region;

-import org.apache.rave.portal.model.RegionWidget;

-import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.*;

 import org.apache.rave.portal.repository.RegionRepository;

 import org.slf4j.Logger;

 import org.slf4j.LoggerFactory;

@@ -149,7 +145,7 @@
         if (trustedDomainObject) {

             trustedRegion = region;

         } else {

-            trustedRegion = getTrustedRegion(region.getEntityId(), trustedRegionContainer);

+            trustedRegion = getTrustedRegion(region.getId(), trustedRegionContainer);

         }

         return isRegionOwnerByUsername(authentication, trustedRegion.getPage().getOwner().getUsername());

     }

@@ -159,7 +155,7 @@
     }

 

     private boolean isRegionOwnerById(Authentication authentication, Long userId) {

-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);

+        return ((User)authentication.getPrincipal()).getId().equals(userId);

     }

 

     private boolean verifyRaveSecurityContext(Authentication authentication, RaveSecurityContext raveSecurityContext) {

@@ -177,18 +173,18 @@
             throw new IllegalArgumentException("unknown RaveSecurityContext type: " + raveSecurityContext.getType());

         }

     }

-    

+

     private boolean isRegionMember(Authentication authentication, Region region, List<Region> trustedRegionContainer, boolean trustedDomainObject, boolean checkEditorStatus) {

         Region trustedRegion = null;

         if (trustedDomainObject) {

             trustedRegion = region;

         } else {

-            trustedRegion = getTrustedRegion(region.getEntityId(), trustedRegionContainer);

+            trustedRegion = getTrustedRegion(region.getId(), trustedRegionContainer);

         }

-        

+

         Page containerPage = trustedRegion.getPage();

-        

-        

+

+

         if (containerPage.getMembers() == null){

             return false;

         }

@@ -198,7 +194,7 @@
         String viewer = ((User)authentication.getPrincipal()).getUsername();

         for (PageUser pageUser:containerPage.getMembers()){

             if (pageUser.getUser().getUsername().equals(viewer)){

-                log.info("User "+viewer+" is a member of page "+containerPage.getEntityId());

+                log.info("User "+viewer+" is a member of page "+containerPage.getId());

                 if(checkEditorStatus){

                     return pageUser.isEditor();

                 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java
index 9d6f1ec..29bd93e 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluator.java
@@ -18,10 +18,7 @@
  */

 package org.apache.rave.portal.security.impl;

 

-import org.apache.rave.portal.model.Page;

-import org.apache.rave.portal.model.PageUser;

-import org.apache.rave.portal.model.RegionWidget;

-import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.*;

 import org.apache.rave.portal.repository.RegionWidgetRepository;

 import org.slf4j.Logger;

 import org.slf4j.LoggerFactory;

@@ -148,7 +145,7 @@
         if (trustedDomainObject) {

             trustedRegionWidget = regionWidget;

         } else {

-            trustedRegionWidget = getTrustedRegionWidget(regionWidget.getEntityId(), trustedRegionWidgetContainer);

+            trustedRegionWidget = getTrustedRegionWidget(regionWidget.getId(), trustedRegionWidgetContainer);

         }

         return isRegionWidgetOwnerByUsername(authentication, getUsernameFromRegionWidget(trustedRegionWidget));

     }

@@ -158,7 +155,7 @@
     }

 

     private boolean isRegionWidgetOwnerById(Authentication authentication, Long userId) {

-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);

+        return ((User)authentication.getPrincipal()).getId().equals(userId);

     }

 

     private boolean verifyRaveSecurityContext(Authentication authentication, RaveSecurityContext raveSecurityContext) {

@@ -176,23 +173,23 @@
             throw new IllegalArgumentException("unknown RaveSecurityContext type: " + raveSecurityContext.getType());

         }

     }

-    

+

     private String getUsernameFromRegionWidget(RegionWidget regionWidget) {

         return regionWidget.getRegion().getPage().getOwner().getUsername();

     }

-    

-    private boolean isRegionWidgetMember(Authentication authentication, 

+

+    private boolean isRegionWidgetMember(Authentication authentication,

             RegionWidget regionWidget, List<RegionWidget> trustedRegionWidgetContainer, boolean trustedDomainObject, boolean checkEditorStatus) {

         RegionWidget trustedRegionWidget = null;

         if (trustedDomainObject) {

             trustedRegionWidget = regionWidget;

         } else {

-            trustedRegionWidget = getTrustedRegionWidget(regionWidget.getEntityId(), trustedRegionWidgetContainer);

+            trustedRegionWidget = getTrustedRegionWidget(regionWidget.getId(), trustedRegionWidgetContainer);

         }

-        

+

         Page containerPage = trustedRegionWidget.getRegion().getPage();

-        

-        

+

+

         if (containerPage.getMembers() == null){

             return false;

         }

@@ -202,7 +199,7 @@
         String viewer = ((User)authentication.getPrincipal()).getUsername();

         for (PageUser pageUser:containerPage.getMembers()){

             if (pageUser.getUser().getUsername().equals(viewer)){

-                log.info("User "+viewer+" is a member of page "+containerPage.getEntityId());

+                log.info("User "+viewer+" is a member of page "+containerPage.getId());

                 if(checkEditorStatus){

                     return pageUser.isEditor();

                 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluator.java
index 4e8784b..0f56f2c 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluator.java
@@ -15,19 +15,19 @@
  */
 package org.apache.rave.portal.security.impl;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
 import org.apache.rave.portal.model.User;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.rave.portal.model.WidgetComment;
 import org.apache.rave.portal.repository.WidgetCommentRepository;
-import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Component;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  */
 @Component
@@ -35,12 +35,12 @@
 
     private Logger log = LoggerFactory.getLogger(getClass());
     private WidgetCommentRepository widgetCommentRepository;
-    
+
     @Autowired
     public DefaultWidgetCommentPermissionEvaluator(WidgetCommentRepository widgetCommentRepository) {
         this.widgetCommentRepository = widgetCommentRepository;
     }
-    
+
     @Override
     public Class<WidgetComment> getType() {
         return WidgetComment.class;
@@ -50,27 +50,27 @@
      * Checks to see if the Authentication object has the supplied Permission
      * on the supplied Page object.  This method invokes the private hasPermission
      * function with the trustedDomainObject parameter set to false since we don't
-     * know if the model being passed in was modified in any way from the 
+     * know if the model being passed in was modified in any way from the
      * actual entity in the database.
-     * 
+     *
      * @param authentication the current Authentication object
      * @param widgetComment the WidgetComment model object
      * @param permission the Permission to check
      * @return true if the Authentication has the proper permission, false otherwise
      */
     @Override
-    public boolean hasPermission(Authentication authentication, WidgetComment widgetComment, Permission permission) {      
+    public boolean hasPermission(Authentication authentication, WidgetComment widgetComment, Permission permission) {
         return hasPermission(authentication, widgetComment, permission, false);
-    }    
+    }
 
     /**
-     * Checks to see if the Authentication object has the supplied Permission 
+     * Checks to see if the Authentication object has the supplied Permission
      * for the Entity represented by the targetId(entityId) and targetType(model class name).
-     * This method invokes the private hasPermission function with the 
+     * This method invokes the private hasPermission function with the
      * trustedDomainObject parameter set to true since we must pull the entity
      * from the database and are guaranteed a trusted domain object,
      * before performing our permission checks.
-     * 
+     *
      * @param authentication the current Authentication object
      * @param targetId the entityId of the model to check, or a RaveSecurityContext object
      * @param targetType the class of the model to check
@@ -81,50 +81,50 @@
     public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Permission permission) {
         boolean hasPermission = false;
         if (targetId instanceof RaveSecurityContext) {
-            hasPermission = verifyRaveSecurityContext(authentication, (RaveSecurityContext)targetId, permission);           
+            hasPermission = verifyRaveSecurityContext(authentication, (RaveSecurityContext)targetId, permission);
         } else {
             hasPermission = hasPermission(authentication, widgetCommentRepository.get((Long)targetId), permission, true);
         }
         return hasPermission;
-    }  
-    
-    private boolean hasPermission(Authentication authentication, WidgetComment widgetComment, Permission permission, boolean trustedDomainObject) {       
-        // this is our container of trusted page objects that can be re-used 
+    }
+
+    private boolean hasPermission(Authentication authentication, WidgetComment widgetComment, Permission permission, boolean trustedDomainObject) {
+        // this is our container of trusted page objects that can be re-used
         // in this method so that the same trusted page object doesn't have to
         // be looked up in the repository multiple times
-        List<WidgetComment> trustedWidgetCommentContainer = new ArrayList<WidgetComment>();                           
-        
+        List<WidgetComment> trustedWidgetCommentContainer = new ArrayList<WidgetComment>();
+
         // first execute the AbstractModelPermissionEvaluator's hasPermission function
-        // to see if it allows permission via it's "higher authority" logic                
+        // to see if it allows permission via it's "higher authority" logic
         if (super.hasPermission(authentication, widgetComment, permission)) {
             return true;
         }
-        
+
         // perform the security logic depending on the Permission type
-        boolean hasPermission = false;                       
-        switch (permission) { 
+        boolean hasPermission = false;
+        switch (permission) {
             case ADMINISTER:
-                // if you are here, you are not an administrator, so you can't administer pages              
+                // if you are here, you are not an administrator, so you can't administer pages
                 break;
             case READ:
                 hasPermission =  true;
                 break;
             case CREATE:
-                hasPermission = isWidgetCommentOwnerById(authentication, widgetComment.getUser().getEntityId());
+                hasPermission = isWidgetCommentOwnerById(authentication, widgetComment.getUser().getId());
                 break;
             case DELETE:
             case UPDATE:
-                // anyone can create, delete, read, or update a page that they own                  
-                hasPermission = isWidgetCommentOwner(authentication, widgetComment, trustedWidgetCommentContainer, trustedDomainObject);     
-                break;   
+                // anyone can create, delete, read, or update a page that they own
+                hasPermission = isWidgetCommentOwner(authentication, widgetComment, trustedWidgetCommentContainer, trustedDomainObject);
+                break;
             default:
                 log.warn("unknown permission: " + permission);
                 break;
         }
-        
+
         return hasPermission;
     }
-    
+
     private boolean verifyRaveSecurityContext(Authentication authentication, RaveSecurityContext raveSecurityContext, Permission permission) {
         Class<?> clazz = null;
         try {
@@ -135,65 +135,62 @@
 
         // perform the permissions check based on the class supplied to the RaveSecurityContext object
         if (WidgetComment.class == clazz) {
-            
-        // perform the security logic depending on the Permission type
-        boolean hasPermission = false;                       
-        switch (permission) { 
-            case ADMINISTER:
-                // if you are here, you are not an administrator, so you can't administer pages              
-                break;
-            case READ:
-                hasPermission = true;
-                break;
-            case CREATE:
-            case DELETE:
-            case UPDATE:
-                // anyone can create, delete, read, or update a page that they own                  
-                hasPermission = isWidgetCommentOwnerById(authentication, (Long)raveSecurityContext.getId());
-                break;   
-            default:
-                log.warn("unknown permission: " + permission);
-                break;
+            // perform the security logic depending on the Permission type
+            boolean hasPermission = false;
+            switch (permission) {
+                case ADMINISTER:
+                    // if you are here, you are not an administrator, so you can't administer pages
+                    break;
+                case READ:
+                    hasPermission = true;
+                    break;
+                case CREATE:
+                case DELETE:
+                case UPDATE:
+                    // anyone can create, delete, read, or update a page that they own
+                    hasPermission = isWidgetCommentOwnerById(authentication, (Long)raveSecurityContext.getId());
+                    break;
+                default:
+                    log.warn("unknown permission: " + permission);
+                    break;
             }
-
             return hasPermission;
         } else {
             throw new IllegalArgumentException("unknown RaveSecurityContext type: " + raveSecurityContext.getType());
         }
-    } 
-    
-    
-    // checks to see if the Authentication object principal is the owner of the supplied widgetComment object 
+    }
+
+    // checks to see if the Authentication object principal is the owner of the supplied widgetComment object
     // if trustedDomainObject is false, pull the entity from the database first to ensure
     // the model object is trusted and hasn't been modified
-    private boolean isWidgetCommentOwner(Authentication authentication, WidgetComment widgetComment, List<WidgetComment> trustedPageContainer, boolean trustedDomainObject) {        
+    private boolean isWidgetCommentOwner(Authentication authentication, WidgetComment widgetComment, List<WidgetComment> trustedPageContainer, boolean trustedDomainObject) {
         WidgetComment trustedWidgetComment = null;
         if (trustedDomainObject) {
             trustedWidgetComment = widgetComment;
         } else {
-            trustedWidgetComment = getTrustedWidgetComment(widgetComment.getEntityId(), trustedPageContainer);
-        }                  
-        
+            trustedWidgetComment = getTrustedWidgetComment(widgetComment.getId(), trustedPageContainer);
+        }
+
         return isWidgetCommentOwnerByUsername(authentication, trustedWidgetComment.getUser().getUsername());
-    }            
-    
+    }
+
     // returns a trusted Page object, either from the PageRepository, or the
     // cached container list
-    private WidgetComment getTrustedWidgetComment(long widgetCommentId, List<WidgetComment> trustedWidgetCommentContainer) {       
+    private WidgetComment getTrustedWidgetComment(long widgetCommentId, List<WidgetComment> trustedWidgetCommentContainer) {
         WidgetComment p = null;
-        if (trustedWidgetCommentContainer.isEmpty()) {           
+        if (trustedWidgetCommentContainer.isEmpty()) {
             p = widgetCommentRepository.get(widgetCommentId);
             trustedWidgetCommentContainer.add(p);
         } else {
             p = trustedWidgetCommentContainer.get(0);
         }
-        return p;       
-    }     
+        return p;
+    }
 
     private boolean isWidgetCommentOwnerByUsername(Authentication authentication, String username) {
         return ((User)authentication.getPrincipal()).getUsername().equals(username);
     }
     private boolean isWidgetCommentOwnerById(Authentication authentication, Long userId) {
-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);
+        return ((User)authentication.getPrincipal()).getId().equals(userId);
     }
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluator.java
index 741fc49..982fcf6 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluator.java
@@ -151,7 +151,7 @@
         if (trustedDomainObject) {

             trustedWidget = widget;

         } else {

-            trustedWidget = getTrustedWidget(widget.getEntityId(), trustedWidgetContainer);

+            trustedWidget = getTrustedWidget(widget.getId(), trustedWidgetContainer);

         }

         return isWidgetOwnerByUsername(authentication, trustedWidget.getOwner().getUsername());

     }

@@ -161,7 +161,7 @@
     }

 

     private boolean isWidgetOwnerById(Authentication authentication, Long userId) {

-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);

+        return ((User)authentication.getPrincipal()).getId().equals(userId);

     }

     

     private boolean isPublishedWidget(Widget widget, List<Widget> trustedWidgetContainer, boolean trustedDomainObject) {

@@ -169,7 +169,7 @@
         if (trustedDomainObject) {

             trustedWidget = widget;

         } else {

-            trustedWidget = getTrustedWidget(widget.getEntityId(), trustedWidgetContainer);

+            trustedWidget = getTrustedWidget(widget.getId(), trustedWidgetContainer);

         }

         return WidgetStatus.PUBLISHED.equals(trustedWidget.getWidgetStatus());

     }    

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluator.java
index 1cde06a..81b8c37 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluator.java
@@ -146,7 +146,7 @@
         if (trustedDomainObject) {

             trustedWidgetRating = widgetRating;

         } else {

-            trustedWidgetRating = getTrustedWidgetRating(widgetRating.getEntityId(), trustedWidgetRatingContainer);

+            trustedWidgetRating = getTrustedWidgetRating(widgetRating.getId(), trustedWidgetRatingContainer);

         }

         return isWidgetRatingOwnerById(authentication, trustedWidgetRating.getUserId());

     }

@@ -156,7 +156,7 @@
     }

 

     private boolean isWidgetRatingOwnerById(Authentication authentication, Long userId) {

-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);

+        return ((User)authentication.getPrincipal()).getId().equals(userId);

     }

 

     private boolean verifyRaveSecurityContext(Authentication authentication, RaveSecurityContext raveSecurityContext) {

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetTagPermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetTagPermissionEvaluator.java
index 6d42a33..5a0c4c7 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetTagPermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/DefaultWidgetTagPermissionEvaluator.java
@@ -110,7 +110,7 @@
                 hasPermission =  true;

                 break;

             case CREATE:

-                hasPermission = isWidgetTagOwnerById(authentication, widgetTag.getUser().getEntityId());

+                hasPermission = isWidgetTagOwnerById(authentication, widgetTag.getUser().getId());

                 break;

             case DELETE:

             case UPDATE:

@@ -170,7 +170,7 @@
         if (trustedDomainObject) {

             trustedWidgetTag = widgetTag;

         } else {

-            trustedWidgetTag = getTrustedWidgetTag(widgetTag.getEntityId(), trustedWidgetTagContainer);

+            trustedWidgetTag = getTrustedWidgetTag(widgetTag.getWidgetId(), widgetTag.getTag().getKeyword(), trustedWidgetTagContainer);

         }                  

         

         return isWidgetTagOwnerByUsername(authentication, trustedWidgetTag.getUser().getUsername());

@@ -178,10 +178,10 @@
     

     // returns a trusted WidgetTag object, either from the WidgetTagRepository, or the

     // cached container list

-    private WidgetTag getTrustedWidgetTag(long widgetTagId, List<WidgetTag> trustedWidgetTagContainer) {

+    private WidgetTag getTrustedWidgetTag(long widgetId, String tagKeyword, List<WidgetTag> trustedWidgetTagContainer) {

         WidgetTag p = null;

         if (trustedWidgetTagContainer.isEmpty()) {

-            p = widgetTagRepository.get(widgetTagId);

+            p = widgetTagRepository.getByWidgetIdAndTag(widgetId, tagKeyword);

             trustedWidgetTagContainer.add(p);

         } else {

             p = trustedWidgetTagContainer.get(0);

@@ -193,6 +193,6 @@
         return ((User)authentication.getPrincipal()).getUsername().equals(username);

     }

     private boolean isWidgetTagOwnerById(Authentication authentication, Long userId) {

-        return ((User)authentication.getPrincipal()).getEntityId().equals(userId);

+        return ((User)authentication.getPrincipal()).getId().equals(userId);

     }

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/RavePermissionEvaluator.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/RavePermissionEvaluator.java
index a9cb828..b2e28ba 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/RavePermissionEvaluator.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/security/impl/RavePermissionEvaluator.java
@@ -19,7 +19,6 @@
 

 package org.apache.rave.portal.security.impl;

 

-import org.apache.rave.persistence.BasicEntity;

 import org.apache.rave.portal.security.ModelPermissionEvaluator;

 import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;

 import org.springframework.beans.factory.annotation.Autowired;

@@ -34,21 +33,21 @@
  * Custom PermissionEvaluator for Rave that stores a map of ModelPermissionEvaluators

  * each of which is responsible for handling Domain Object Security for the Rave Model

  * objects

- * 

+ *

  * @author carlucci

  */

 @Component

 public class RavePermissionEvaluator implements PermissionEvaluator {

-    private Map<String, ModelPermissionEvaluator<?>> modelPermissionEvaluatorMap;

-    

+    private Map<Class, ModelPermissionEvaluator<?>> modelPermissionEvaluatorMap;

+

     /**

-     * Constructor which will take in a component-scanned list of all ModelPermissionEvaluator 

-     * classes found by Spring component scanner.  The constructor builds the 

+     * Constructor which will take in a component-scanned list of all ModelPermissionEvaluator

+     * classes found by Spring component scanner.  The constructor builds the

      * internal Map by using the Model type (Model Class) as the key, thus ensuring

      * only one ModelPermissionEvaluator class exists for each Model object.  The

      * constructor first sorts the injected list of ModelPermissionEvaluator objects

      * by the loadOrder field to allow overrides of the default ModelPermissionEvaluators.

-     * 

+     *

      * @param modelPermissionEvaluatorList autowired injected list of all ModelPermissionEvaluator classes found

      *                                     by the component scanner

      */

@@ -63,19 +62,19 @@
             public int compare(ModelPermissionEvaluator o1, ModelPermissionEvaluator o2) {

                 return new Integer(o1.getLoadOrder()).compareTo(new Integer(o2.getLoadOrder()));

             }

-        }); 

-        

+        });

+

         // build the map using the model type/class as the key

-        modelPermissionEvaluatorMap = new HashMap<String, ModelPermissionEvaluator<?>>();

+        modelPermissionEvaluatorMap = new HashMap<Class, ModelPermissionEvaluator<?>>();

         for (ModelPermissionEvaluator<?> mpe : modelPermissionEvaluatorList) {

-            modelPermissionEvaluatorMap.put(mpe.getType().getName(), mpe);

+            modelPermissionEvaluatorMap.put(mpe.getType(), mpe);

         }

     }

-    

+

     /**

-     * Checks to see if the Authentication object has the supplied permission  

+     * Checks to see if the Authentication object has the supplied permission

      * on the supplied domain object

-     * 

+     *

      * @param authentication the Authentication object

      * @param targetDomainObject the domain object needing permission check

      * @param permissionString the permission to check

@@ -88,17 +87,17 @@
             return false;

         }

         // find the appropriate ModelPermissionEvaluator from the map based on

-        // the targetDomainObject's class and invoke the hasPermission function        

-        return getEvaluator(targetDomainObject.getClass().getName()).hasPermission(authentication, targetDomainObject,

+        // the targetDomainObject's class and invoke the hasPermission function

+        return getEvaluator(targetDomainObject.getClass()).hasPermission(authentication, targetDomainObject,

                 getPermission(targetDomainObject, (String) permissionString));

     }

 

     /**

-     * Checks to see if the Authentication object has the supplied permission 

+     * Checks to see if the Authentication object has the supplied permission

      * on the supplied targetType (model class name) and targetId (entityId).

      * This method can be used when a permission check is needed and the method

-     * does not currently have the domain object, only its entityId     

-     * 

+     * does not currently have the domain object, only its entityId

+     *

      * @param authentication the Authentication object

      * @param targetId the entityId of the targetType class

      * @param targetType the class name of the domain object

@@ -107,26 +106,58 @@
      */

     @Override

     public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permissionString) {

-        // find the appropriate ModelPermissionEvaluator from the map based on 

+        // find the appropriate ModelPermissionEvaluator from the map based on

         // the targetType and invoke the hasPermission function

         Permission permission = Permission.fromString((String) permissionString);

         if (permission == Permission.CREATE_OR_UPDATE) {

             throw new IllegalArgumentException("CREATE_OR_UPDATE not supported in this context.");

         }

-        return getEvaluator(targetType).hasPermission(authentication, targetId, targetType, permission);

-    }    

-     

-    private ModelPermissionEvaluator getEvaluator(String targetType) throws IllegalArgumentException {        

+

+        // The targetType comes in as a String representing the Class (from the Spring annotations)

+        // so we need to convert it to a Class

+        Class clazz = null;

+        try {

+            clazz = Class.forName(targetType);

+        } catch (ClassNotFoundException e) {

+            throw new IllegalArgumentException("Class " + targetType + " not found", e);

+        }

+

+        return getEvaluator(clazz).hasPermission(authentication, targetId, targetType, permission);

+    }

+

+    private ModelPermissionEvaluator getEvaluator(Class targetType) throws IllegalArgumentException {

         ModelPermissionEvaluator mpe = modelPermissionEvaluatorMap.get(targetType);

         if (mpe == null) {

-            throw new IllegalArgumentException("ModelPermissionEvaluator not found for type " + targetType);

+            // search for and register a compatible MPE

+            mpe = findAndRegisterCompatibleModelPermissionEvaluator(targetType);

+            // at this point, if we still haven't found a compatible MPE, throw exception

+            if (mpe == null) {

+                throw new IllegalArgumentException("ModelPermissionEvaluator not found for type " + targetType);

+            }

         }

         return mpe;

     }

 

+    private ModelPermissionEvaluator findAndRegisterCompatibleModelPermissionEvaluator(Class modelClass) {

+        // look to see if this model class implements one of the types of the registered MPE's

+        // and add an entry into the map for it.  This will allow, for example, a JpaPage class

+        // to use the registered MPE for the Page interface

+        for (Map.Entry<Class, ModelPermissionEvaluator<?>> classModelPermissionEvaluatorEntry : modelPermissionEvaluatorMap.entrySet()) {

+            Class registeredModelClass = classModelPermissionEvaluatorEntry.getKey();

+            ModelPermissionEvaluator<?> registeredMpe = classModelPermissionEvaluatorEntry.getValue();

+            if (registeredModelClass.isAssignableFrom(modelClass)) {

+                // register this new mapping of model class to mpe class

+                modelPermissionEvaluatorMap.put(modelClass, registeredMpe);

+                return registeredMpe;

+            }

+        }

+        // we didn't find a compatible ModelPermissionEvaluator...

+        return null;

+    }

+

     private Permission getPermission(Object targetDomainObject, String permissionString) {

         Permission permission = Permission.fromString((String) permissionString);

-        if (permission.equals(Permission.CREATE_OR_UPDATE)) {

+  /*      if (permission.equals(Permission.CREATE_OR_UPDATE)) {

             if (targetDomainObject instanceof BasicEntity) {

                 Long id = ((BasicEntity) targetDomainObject).getEntityId();

                 if (id == null) {

@@ -137,7 +168,7 @@
             } else {

                 throw new IllegalArgumentException("CREATE_OR_UPDATE is currently only supported for BasicEntity types");

             }

-        }

+        }*/

         return permission;

     }

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/AuthorityService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/AuthorityService.java
index 6f571e8..dfbc3b2 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/AuthorityService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/AuthorityService.java
@@ -25,7 +25,7 @@
 public interface AuthorityService {
 
     /**
-     * @param entityId unique identifier of the {@link Authority}
+     * @param entityId unique identifier of the {@link org.apache.rave.portal.model.Authority}
      * @return Authority if it can be found, otherwise {@literal null}
      */
     Authority getAuthorityById(long entityId);
@@ -37,13 +37,13 @@
     Authority getAuthorityByName(String authorityName);
 
     /**
-     * @return a {@link SearchResult} with all {@link Authority}'s
+     * @return a {@link SearchResult} with all {@link org.apache.rave.portal.model.Authority}'s
      */
     SearchResult<Authority> getAllAuthorities();
-    
+
      /**
-     * @return a {@link SearchResult} with the list of all default 
-     * {@link Authority}'s
+     * @return a {@link SearchResult} with the list of all default
+     * {@link org.apache.rave.portal.model.Authority}'s
      */
     SearchResult<Authority> getDefaultAuthorities();
 }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/NewAccountService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/NewAccountService.java
index d448e0e..7d0bfb1 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/NewAccountService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/NewAccountService.java
@@ -26,7 +26,7 @@
     /**
      * Creates a new account using several other Rave services.
      *
-     * @param newUser the {@link User} from which a new {@link org.apache.rave.portal.model.User} can be created
+     * @param newUser the {@link org.apache.rave.portal.model.User} from which a new {@link org.apache.rave.portal.model.User} can be created
      * @throws Exception in case something goes wrong
      */
     public void createNewAccount(User newUser) throws Exception;
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PortalPreferenceService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PortalPreferenceService.java
index 4b89cf2..a2e0ebe 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PortalPreferenceService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/PortalPreferenceService.java
@@ -30,14 +30,14 @@
 public interface PortalPreferenceService {
 
     /**
-     * Creates a Map of all {@link PortalPreference}'s using the preference key as key for the Map.Entry
+     * Creates a Map of all {@link org.apache.rave.portal.model.PortalPreference}'s using the preference key as key for the Map.Entry
      *
      * @return Map of PortalPreference's
      */
     Map<String, PortalPreference> getPreferencesAsMap();
 
     /**
-     * Gets a {@link PortalPreference} by its key
+     * Gets a {@link org.apache.rave.portal.model.PortalPreference} by its key
      *
      * @param key unique name of the preference
      * @return PortalPreference if it exists, otherwise {@literal null}
@@ -45,7 +45,7 @@
     PortalPreference getPreference(String key);
 
     /**
-     * Saves a {@link PortalPreference} with a single value.
+     * Saves a {@link org.apache.rave.portal.model.PortalPreference} with a single value.
      * If a PortalPreference already exists with this key, its value(s) will be overwritten.
      *
      * @param key   of the preference, e.g. {@literal title}
@@ -54,7 +54,7 @@
     void savePreference(String key, String value);
 
     /**
-     * Saves a {@link PortalPreference} with a List of values.
+     * Saves a {@link org.apache.rave.portal.model.PortalPreference} with a List of values.
      * If a PortalPreference already exists with this key, its value(s) will be overwritten.
      *
      * @param key    of the preference, e.g. {@literal colors}
@@ -63,7 +63,7 @@
     void savePreference(String key, List<String> values);
 
     /**
-     * Saves a {@link PortalPreference}
+     * Saves a {@link org.apache.rave.portal.model.PortalPreference}
      *
      * @param preference PortalPreference to save
      */
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/UserService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/UserService.java
index a4f13a1..4745747 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/UserService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/UserService.java
@@ -19,13 +19,13 @@
 

 package org.apache.rave.portal.service;

 

-import java.util.List;

-

 import org.apache.rave.portal.model.Person;

 import org.apache.rave.portal.model.User;

 import org.apache.rave.portal.model.util.SearchResult;

 import org.springframework.security.core.userdetails.UserDetailsService;

 

+import java.util.List;

+

 public interface UserService extends UserDetailsService {

     /**

      * Get the currently authenticated user.

@@ -57,7 +57,7 @@
      * Return the requested user object using the user's name.

      *

      * @param userName (unique) name of the user

-     * @return {@link User} if one exists, otherwise {@literal null}

+     * @return {@link org.apache.rave.portal.model.User} if one exists, otherwise {@literal null}

      */

     User getUserByUsername(String userName);

 

@@ -65,7 +65,7 @@
      * Return a user object by the user ID.

      *

      * @param id the user ID

-     * @return {@link User} if one exists, otherwise {@literal null}

+     * @return {@link org.apache.rave.portal.model.User} if one exists, otherwise {@literal null}

      */

     User getUserById(Long id);

 

@@ -73,7 +73,7 @@
      * Return a user object by the user email.

      *

      * @param userEmail email address of the user

-     * @return {@link User} if one exists, otherwise {@literal null}

+     * @return {@link org.apache.rave.portal.model.User} if one exists, otherwise {@literal null}

      */

     User getUserByEmail(String userEmail);

 

@@ -85,7 +85,7 @@
     void updateUserProfile(User user);

 

     /**

-     * Gets a limited {@link SearchResult} for {@link User}'s

+     * Gets a limited {@link SearchResult} for {@link org.apache.rave.portal.model.User}'s

      *

      * @param offset   start point within the resultset (for paging)

      * @param pageSize maximum number of items to be returned (for paging)

@@ -94,7 +94,7 @@
     SearchResult<User> getLimitedListOfUsers(int offset, int pageSize);

 

     /**

-     * Gets a {@link SearchResult} for {@link User}'s that match the search term

+     * Gets a {@link SearchResult} for {@link org.apache.rave.portal.model.User}'s that match the search term

      *

      * @param searchTerm free text input to search on users

      * @param offset     start point within the resultset (for paging)

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetCommentService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetCommentService.java
index 671d0f8..2fa8583 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetCommentService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetCommentService.java
@@ -20,14 +20,14 @@
 import org.springframework.security.access.prepost.PreAuthorize;
 
 public interface WidgetCommentService {
-    
+
     @PostAuthorize("hasPermission(returnObject, 'read')")
     WidgetComment getWidgetComment(Long id);
-    
+
     @PreAuthorize("hasPermission(#widgetComment, 'create_or_update')")
     void saveWidgetComment(WidgetComment widgetComment);
-    
-    @PreAuthorize("hasPermission(#id, 'org.apache.rave.portal.model.WidgetComment', 'delete')") 
+
+    @PreAuthorize("hasPermission(#id, 'org.apache.rave.portal.model.WidgetComment', 'delete')")
     void removeWidgetComment(Long id);
 
     /**
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java
index 6e963b7..9bfdad0 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/WidgetRatingService.java
@@ -28,7 +28,7 @@
 public interface WidgetRatingService {

 

     /**

-     * Gets a {@link WidgetRating} for the widgetId and userId

+     * Gets a {@link org.apache.rave.portal.model.WidgetRating} for the widgetId and userId

      *

      * @param widgetId unique identifier for a Widget

      * @param userId   unique identifier for a User

@@ -38,7 +38,7 @@
     WidgetRating getByWidgetIdAndUserId(Long widgetId, Long userId);

 

     /**

-     * Updates the score of a {@link WidgetRating}

+     * Updates the score of a {@link org.apache.rave.portal.model.WidgetRating}

      *

      * @param widgetRating WidgetRating

      * @param score        value of the rating

@@ -47,7 +47,7 @@
     void updateScore(WidgetRating widgetRating, Integer score);

 

     /**

-     * Saves a {@link WidgetRating} for a widget

+     * Saves a {@link org.apache.rave.portal.model.WidgetRating} for a widget

      *

      * @param rating   WidgetRating

      */

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultCategoryService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultCategoryService.java
index 3ad7172..56e67bb 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultCategoryService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultCategoryService.java
@@ -16,6 +16,7 @@
 package org.apache.rave.portal.service.impl;

 

 import org.apache.rave.portal.model.Category;

+import org.apache.rave.portal.model.impl.CategoryImpl;

 import org.apache.rave.portal.model.User;

 import org.apache.rave.portal.repository.CategoryRepository;

 import org.apache.rave.portal.service.CategoryService;

@@ -52,7 +53,7 @@
     @Override

     @Transactional

     public Category create(String text, User createdUser) {

-        Category category = new Category();

+        Category category = new CategoryImpl();

         Date now = new Date();

         category.setText(text);

         category.setCreatedDate(now);

@@ -77,7 +78,7 @@
     @Override

     @Transactional

     public void delete(Category category) {

-        Category categoryToBeDeleted = categoryRepository.get(category.getEntityId());

+        Category categoryToBeDeleted = categoryRepository.get(category.getId());

         categoryRepository.delete(categoryToBeDeleted);

     }

 }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java
index 9a6ee89..64bc5d6 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java
@@ -21,6 +21,7 @@
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.AuthorityService;
 import org.apache.rave.portal.service.NewAccountService;
 import org.apache.rave.portal.service.PageLayoutService;
@@ -64,7 +65,7 @@
 
         throwExceptionIfUserExists(userName, email);
 
-        User user = new User();
+        User user = new UserImpl();
         //set the required fields
         user.setUsername(userName);
         user.setEmail(email);
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
index 65291f6..4f13e54 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
@@ -19,22 +19,12 @@
 

 package org.apache.rave.portal.service.impl;

 

-import java.util.ArrayList;

-import java.util.List;

-

-import javax.persistence.NoResultException;

-import javax.persistence.NonUniqueResultException;

-

 import org.apache.rave.persistence.Repository;

-import org.apache.rave.portal.model.Page;

-import org.apache.rave.portal.model.PageInvitationStatus;

-import org.apache.rave.portal.model.PageLayout;

-import org.apache.rave.portal.model.PageType;

-import org.apache.rave.portal.model.PageUser;

-import org.apache.rave.portal.model.Region;

-import org.apache.rave.portal.model.RegionWidget;

-import org.apache.rave.portal.model.User;

-import org.apache.rave.portal.model.Widget;

+import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.PageImpl;

+import org.apache.rave.portal.model.impl.PageUserImpl;

+import org.apache.rave.portal.model.impl.RegionImpl;

+import org.apache.rave.portal.model.impl.RegionWidgetImpl;

 import org.apache.rave.portal.repository.PageLayoutRepository;

 import org.apache.rave.portal.repository.PageRepository;

 import org.apache.rave.portal.repository.PageTemplateRepository;

@@ -48,6 +38,11 @@
 import org.springframework.stereotype.Service;

 import org.springframework.transaction.annotation.Transactional;

 

+import javax.persistence.NoResultException;

+import javax.persistence.NonUniqueResultException;

+import java.util.ArrayList;

+import java.util.List;

+

 @Service

 public class DefaultPageService implements PageService {

     private final PageRepository pageRepository;

@@ -105,9 +100,12 @@
 

     @Override

     public Page getPageFromList(long pageId, List<Page> pages) {

-        Page pageToFind = new Page(pageId);

-        int index = pages.indexOf(pageToFind);

-        return index == -1 ? null : pages.get(index);

+       for(Page page: pages) {

+           if(page.getId().equals(pageId)){

+               return page;

+           }

+       }

+       return null;

     }

 

     @Override

@@ -140,7 +138,7 @@
         List<Page> parentsSubPages = new ArrayList<Page>();

         int regionCount;

         for (regionCount = 0; regionCount < pageLayout.getNumberOfRegions(); regionCount++) {

-            Region region = new Region();

+            Region region = new RegionImpl();

             region.setRenderOrder(regionCount);

             // TODO: this should eventually be defined by the PageTemplateRegion.locked field

             region.setLocked(false);

@@ -149,7 +147,7 @@
 

         // Create a Page object and register it.

         long renderSequence = (parentPage.getSubPages() != null) ? parentPage.getSubPages().size() + 1 : 1;

-        Page page = new Page();

+        Page page = new PageImpl();

         page.setName(pageName);

         page.setOwner(user);

         page.setPageLayout(pageLayout);

@@ -157,7 +155,7 @@
         // set this as a "sub-page" page type

         page.setPageType(PageType.SUB_PAGE);

 

-        PageUser pageUser = new PageUser(page.getOwner(), page, renderSequence);

+        PageUser pageUser = new PageUserImpl(page.getOwner(), page, renderSequence);

         pageUser.setPageStatus(PageInvitationStatus.OWNER);

         List<PageUser> members = new ArrayList<PageUser>();

         members.add(pageUser);

@@ -190,7 +188,7 @@
 

         //TODO RAVE-237:  We should be able to delete these lines.  If there are gaps in the sequence numbers, then it will still

         //TODO RAVE-237:  return values in the correct order.  We only need to update sequences when there is a change in order

-        List<PageUser> thisUsersPages = new ArrayList<PageUser>(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER));

+        List<PageUser> thisUsersPages = new ArrayList<PageUser>(pageRepository.getPagesForUser(user.getId(), PageType.USER));

         updatePageRenderSequences(thisUsersPages);

     }

 

@@ -248,7 +246,7 @@
         RegionWidget regionWidget = getFromRepository(regionWidgetId, regionWidgetRepository);

         verifyRegionWidgetIsNotLocked(regionWidget);

         regionWidgetRepository.delete(regionWidget);

-        return getFromRepository(regionWidget.getRegion().getEntityId(), regionRepository);

+        return getFromRepository(regionWidget.getRegion().getId(), regionRepository);

     }

 

     @Override

@@ -306,11 +304,11 @@
     @Transactional

     public Boolean addMemberToPage(long pageId, long userId){

         Page page = getPage(pageId);

-        PageUser pageUser = new PageUser();

+        PageUser pageUser = new PageUserImpl();

         pageUser.setUser(userService.getUserById(userId));

         pageUser.setPage(page);

         pageUser.setPageStatus(PageInvitationStatus.PENDING);

-        List<PageUser> thisUsersPages = pageRepository.getPagesForUser(userService.getUserById(userId).getEntityId(), PageType.USER);

+        List<PageUser> thisUsersPages = pageRepository.getPagesForUser(userService.getUserById(userId).getId(), PageType.USER);

         pageUser.setRenderSequence(new Long(thisUsersPages.size() + 1));

         page.getMembers().add(pageUser);

         if(pageRepository.save(page) != null){

@@ -325,7 +323,7 @@
         Page page = this.getPage(pageId);

         PageUser pageUserToRemove = null;

         for(PageUser pageUser : page.getMembers()){

-            if(pageUser.getUser().getEntityId().equals(userId)){

+            if(pageUser.getUser().getId().equals(userId)){

                 pageUserToRemove = pageUser;

                 break;

             }

@@ -400,7 +398,7 @@
 

         //add as many missing regions as the new layout requires

         for (int i=0; i < numberOfNewRegionsToAdd; i++) {

-            Region newRegion = new Region();

+            Region newRegion = new RegionImpl();

             newRegion.setPage(page);

             newRegion.setRenderOrder(lastRegionRenderOrder++);

             newRegion.setLocked(false);

@@ -447,7 +445,7 @@
     }

 

     private RegionWidget createWidgetInstance(Widget widget, Region region, int position) {

-        RegionWidget regionWidget = new RegionWidget();

+        RegionWidget regionWidget = new RegionWidgetImpl();

         regionWidget.setRenderOrder(position);

         regionWidget.setWidget(widget);

         // TODO: setLocked and setHideChrome are hard-coded to false for new widgets manually added by users

@@ -486,7 +484,7 @@
         List<Region> regions = new ArrayList<Region>();

         int regionCount;

         for (regionCount = 0; regionCount < pageLayout.getNumberOfRegions(); regionCount++) {

-            Region region = new Region();

+            Region region = new RegionImpl();

             region.setRenderOrder(regionCount);

             // TODO: this should eventually be defined by the PageTemplateRegion.locked field

             region.setLocked(false);

@@ -494,7 +492,7 @@
         }

         // Get all User Pages

         Page page = null;

-        List<Page> defaultUserPage = pageRepository.getAllPages(user.getEntityId(), PageType.USER);

+        List<Page> defaultUserPage = pageRepository.getAllPages(user.getId(), PageType.USER);

         // Is there a default page for this user

         if (defaultUserPage.isEmpty()) {

             // Do we have a default User template defined, if so create the page based on the template

@@ -510,11 +508,11 @@
         // If we have a page already or if there was an exception from above then create the page

         // Create the new page for the user

         long renderSequence = defaultUserPage.size() + 1;

-        page = new Page();

+        page = new PageImpl();

         page.setName(pageName);

         page.setOwner(user);

         page.setPageLayout(pageLayout);

-        PageUser pageUser = new PageUser(page.getOwner(), page, renderSequence);

+        PageUser pageUser = new PageUserImpl(page.getOwner(), page, renderSequence);

         pageUser.setPageStatus(PageInvitationStatus.OWNER);

         pageUser.setEditor(true);

 

@@ -525,8 +523,7 @@
         page.setRegions(regions);

         // set this as a "user" page type

         page.setPageType(PageType.USER);

-        pageRepository.save(page);

-        return page;

+        return pageRepository.save(page);

     }

 

     private void updatePageRenderSequences(List<PageUser> pages) {

@@ -546,18 +543,18 @@
         // get the logged in user

         User user = userService.getAuthenticatedUser();

         // get the page to move and the page to move after

-        PageUser movingPageUser = pageRepository.getSingleRecord(user.getEntityId(), pageId);

+        PageUser movingPageUser = pageRepository.getSingleRecord(user.getId(), pageId);

         PageUser afterPageUser = null;

         int newIndex = 0;

         // check to see if we should move the page to beginning

         if (moveAfterPageId != MOVE_PAGE_DEFAULT_POSITION_INDEX) {

-            afterPageUser = pageRepository.getSingleRecord(user.getEntityId(), moveAfterPageId);

+            afterPageUser = pageRepository.getSingleRecord(user.getId(), moveAfterPageId);

         }

 

         // get all of the user's pages

         // the pageRepository returns an un-modifiable list

         // so we need to create a modifyable arraylist

-        List<PageUser> thisUsersPages = new ArrayList<PageUser>(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER));

+        List<PageUser> thisUsersPages = new ArrayList<PageUser>(pageRepository.getPagesForUser(user.getId(), PageType.USER));

         // first remove it from the list

         if (!thisUsersPages.remove(movingPageUser)) {

             throw new RuntimeException("unable to find pageId " + pageId + " attempted to be moved for user " + user);

@@ -590,7 +587,7 @@
 

     private static RegionWidget findRegionWidgetById(Long id, List<RegionWidget> regionWidgets) {

         for (RegionWidget widget : regionWidgets) {

-            if (widget.getEntityId().equals(id)) {

+            if (widget.getId().equals(id)) {

                 return widget;

             }

         }

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceService.java
index 7584cf4..21af0d8 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceService.java
@@ -20,10 +20,12 @@
 package org.apache.rave.portal.service.impl;
 
 import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.impl.PortalPreferenceImpl;
 import org.apache.rave.portal.repository.PortalPreferenceRepository;
 import org.apache.rave.portal.service.PortalPreferenceService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -60,6 +62,7 @@
     }
 
     @Override
+    @Transactional
     public void savePreference(String key, String value) {
         List<String> values = new ArrayList<String>();
         values.add(value);
@@ -67,10 +70,11 @@
     }
 
     @Override
+    @Transactional
     public void savePreference(String key, List<String> values) {
         PortalPreference preference = getPreference(key);
         if (preference == null) {
-            preference = new PortalPreference(key, values);
+            preference = new PortalPreferenceImpl(key, values);
         } else {
             preference.setValues(values);
         }
@@ -78,6 +82,7 @@
     }
 
     @Override
+    @Transactional
     public void savePreference(PortalPreference preference) {
         repository.save(preference);
     }
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultUserService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultUserService.java
index 53a0c8c..b36c581 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultUserService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultUserService.java
@@ -20,13 +20,6 @@
 package org.apache.rave.portal.service.impl;

 

 

-import java.util.ArrayList;

-import java.util.Calendar;

-import java.util.Date;

-import java.util.HashMap;

-import java.util.List;

-import java.util.Map;

-

 import org.apache.commons.lang.StringUtils;

 import org.apache.rave.portal.model.PageType;

 import org.apache.rave.portal.model.Person;

@@ -52,6 +45,8 @@
 import org.springframework.stereotype.Service;

 import org.springframework.transaction.annotation.Transactional;

 

+import java.util.*;

+

 /**

  *

  */

@@ -211,6 +206,7 @@
     }

 

     @Override

+    @Transactional

     public void updateUserProfile(User user) {

         userRepository.save(user);

     }

@@ -318,7 +314,7 @@
             throw new IllegalArgumentException("Could not find user for email " + newUser.getEmail());

         }

         // create user hash:

-        String input = user.getEmail() + user.getUsername() + String.valueOf(user.getEntityId()) + System.nanoTime();

+        String input = user.getEmail() + user.getUsername() + String.valueOf(user.getId()) + System.nanoTime();

         // hash needs to be URL friendly:

         String safeString = new String(Base64.encode(passwordEncoder.encode(input).getBytes()));

         String  hashedInput = safeString.replaceAll("[/=]", "A");

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentService.java b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentService.java
index bf3701d..69abdeb 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentService.java
+++ b/rave-components/rave-core/src/main/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentService.java
@@ -25,14 +25,14 @@
 
 @Service
 public class DefaultWidgetCommentService implements WidgetCommentService {
-    
+
     private final WidgetCommentRepository widgetCommentRepository;
-    
+
     @Autowired
     public DefaultWidgetCommentService(WidgetCommentRepository widgetCommentRepository) {
         this.widgetCommentRepository = widgetCommentRepository;
     }
-    
+
     @Override
     public WidgetComment getWidgetComment(Long id) {
         return widgetCommentRepository.get(id);
diff --git a/rave-components/rave-core/src/main/resources/META-INF/persistence.xml b/rave-components/rave-core/src/main/resources/META-INF/persistence.xml
deleted file mode 100644
index c833ac0..0000000
--- a/rave-components/rave-core/src/main/resources/META-INF/persistence.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one
-  ~ or more contributor license agreements.  See the NOTICE file
-  ~ distributed with this work for additional information
-  ~ regarding copyright ownership.  The ASF licenses this file
-  ~ to you 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.
-  -->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-            xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
-            version="2.0">
-        <persistence-unit name="ravePersistenceUnit" transaction-type="RESOURCE_LOCAL">
-            <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-            <class>org.apache.rave.portal.model.Page</class>
-            <class>org.apache.rave.portal.model.Region</class>
-            <class>org.apache.rave.portal.model.User</class>
-            <class>org.apache.rave.portal.model.RegionWidget</class>
-            <class>org.apache.rave.portal.model.RegionWidgetPreference</class>
-            <class>org.apache.rave.portal.model.Widget</class>
-            <class>org.apache.rave.portal.model.WidgetComment</class>
-            <class>org.apache.rave.portal.model.WidgetRating</class>
-            <class>org.apache.rave.portal.model.PageLayout</class>
-            <class>org.apache.rave.portal.model.Authority</class>
-            <class>org.apache.rave.portal.model.Tag</class>
-            <class>org.apache.rave.portal.model.WidgetTag</class>
-            <class>org.apache.rave.portal.model.PortalPreference</class>
-            <class>org.apache.rave.portal.model.PageTemplate</class>
-            <class>org.apache.rave.portal.model.PageTemplateRegion</class>
-            <class>org.apache.rave.portal.model.PageTemplateWidget</class>
-            <class>org.apache.rave.portal.model.PageUser</class>
-        </persistence-unit>
-</persistence>
diff --git a/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml b/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml
index d9e1da4..4c87dd7 100644
--- a/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml
+++ b/rave-components/rave-core/src/main/resources/org/apache/rave/core-applicationContext.xml
@@ -55,39 +55,6 @@
     <context:component-scan base-package="org.apache.rave.portal.service"/>
     <context:component-scan base-package="org.apache.rave.portal.security"/>
 
-    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
-        <property name="entityManagerFactory" ref="entityManagerFactory"/>
-    </bean>
-
-    <tx:annotation-driven transaction-manager="transactionManager"/>
-
-    <bean id="entityManagerFactory"
-          class="org.apache.rave.persistence.jpa.PopulatedLocalContainerEntityManagerFactory">
-        <property name="populator" ref="dataSourcePopulator"/>
-        <property name="loadTimeWeaver">
-            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
-        </property>
-        <property name="persistenceUnitName" value="ravePersistenceUnit"/>
-        <property name="dataSource" ref="dataSource"/>
-        <property name="jpaVendorAdapter">
-            <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
-                  p:databasePlatform="${portal.jpaVendorAdapter.databasePlatform}"
-                  p:database="${portal.jpaVendorAdapter.database}"
-                  p:showSql="${portal.jpaVendorAdapter.showSql}"/>
-        </property>
-        <property name="jpaDialect">
-            <bean class="${portal.jpaDialect}"/>
-        </property>
-        <property name="jpaPropertyMap">
-            <map>
-                <entry key="openjpa.Log" value="${portal.openjpa.Log}"/>
-                <entry key="openjpa.RuntimeUnenhancedClasses" value="${portal.openjpa.RuntimeUnenhancedClasses}"/>
-                <entry key="openjpa.jdbc.SynchronizeMappings" value="${portal.openjpa.jdbc.SynchronizeMappings}"/>
-                <entry key="openjpa.jdbc.MappingDefaults" value="${portal.openjpa.jdbc.MappingDefaults}"/>
-            </map>
-        </property>
-    </bean>
-
     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
         <property name="url" value="${portal.dataSource.url}"/>
         <property name="driverClassName" value="${portal.dataSource.driver}"/>
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetCommentTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetCommentTest.java
deleted file mode 100644
index 1ccab4c..0000000
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetCommentTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2011 The Apache Software Foundation.
- *
- * 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.rave.portal.model;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Date;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-/**
- *
- * @author ISIS
- */
-public class WidgetCommentTest {
-    
-    private WidgetComment widgetComment;
-    
-    private static final Long VALID_ENTITY_ID = 1L;
-    private static final Long VALID_USER_ID = 1L;
-    private static final Long VALID_WIDGET_ID = 3L;
-    private static final String VALID_COMMENT = "comment";
-    private static final Date VALID_CREATED_DATE = new Date();
-    private static final Date VALID_LAST_MODIFIED_DATE = new Date();
-    
-    @Before
-    public void setUp() {
-        widgetComment = new WidgetComment();
-        widgetComment.setEntityId(VALID_ENTITY_ID);
-        widgetComment.setWidgetId(VALID_WIDGET_ID);
-        widgetComment.setUser(new User(1L, "John.Doe"));
-        widgetComment.setText(VALID_COMMENT);
-        widgetComment.setCreatedDate(VALID_CREATED_DATE);
-        widgetComment.setLastModifiedDate(VALID_LAST_MODIFIED_DATE);
-    }
-    
-    @Test
-    public void getters() {
-        assertEquals(VALID_ENTITY_ID, widgetComment.getEntityId());
-        assertEquals(VALID_WIDGET_ID, widgetComment.getWidgetId());
-        assertEquals(VALID_USER_ID, widgetComment.getUser().getEntityId());
-        assertEquals(VALID_CREATED_DATE, widgetComment.getCreatedDate());
-        assertEquals(VALID_LAST_MODIFIED_DATE, widgetComment.getLastModifiedDate());
-    }
-    
-    @Test
-    public void utility() {
-        assertNotNull(widgetComment);
-
-        String toString = widgetComment.toString();
-        assertNotNull(toString);
-
-        int hashCode = widgetComment.hashCode();
-        assertEquals(hashCode, widgetComment.hashCode());
-
-        assertFalse(widgetComment.equals(new WidgetComment()));
-        assertFalse(widgetComment.equals(new String()));
-        assertFalse(new WidgetComment().equals(widgetComment));
-        WidgetComment testWidgetComment = new WidgetComment();
-        testWidgetComment.setEntityId(VALID_ENTITY_ID);
-        assertTrue(widgetComment.equals(testWidgetComment));
-    }
-}
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/util/ModelUtilsTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/util/ModelUtilsTest.java
index 0711a2b..739e08a 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/util/ModelUtilsTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/util/ModelUtilsTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.model.util;

 

 import org.apache.rave.portal.model.RegionWidgetPreference;

+import org.apache.rave.portal.model.impl.RegionWidgetPreferenceImpl;

 import org.junit.Test;

 

 import java.util.Arrays;

@@ -32,7 +33,7 @@
 

     @Test

     public void normalizeRegionWidgetPreference() {

-        RegionWidgetPreference testPreference = new RegionWidgetPreference(null, null, "camelCaseName", "FOO");

+        RegionWidgetPreference testPreference = new RegionWidgetPreferenceImpl( null, "camelCaseName", "FOO");

         ModelUtils.normalizeRegionWidgetPreference(VALID_REGION_WIDGET_ID, testPreference);

 

         assertTrue(testPreference.getRegionWidgetId() == VALID_REGION_WIDGET_ID);

@@ -48,8 +49,8 @@
     }

 

     public List<RegionWidgetPreference> getTestRegionWidgetPreferences() {

-        return Arrays.asList(new RegionWidgetPreference(null, null, "camelCaseName", "FOO"),

-                new RegionWidgetPreference(null, 20L, "lowercasename", "FOO"),

-                new RegionWidgetPreference(null, -100L, "UPPERCASENAME", "FOO"));

+        return Arrays.asList((RegionWidgetPreference)new RegionWidgetPreferenceImpl( null, "camelCaseName", "FOO"),

+                (RegionWidgetPreference)new RegionWidgetPreferenceImpl(20L, "lowercasename", "FOO"),

+                (RegionWidgetPreference)new RegionWidgetPreferenceImpl( -100L, "UPPERCASENAME", "FOO"));

     }

 }
\ No newline at end of file
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java
deleted file mode 100644
index 8ce8648..0000000
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.portal.repository;
-
-import org.apache.rave.persistence.BasicEntity;
-import org.apache.rave.persistence.Repository;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.annotation.Rollback;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.CoreMatchers.sameInstance;
-import static org.junit.Assert.assertThat;
-
-/**
- */
-
-@Transactional
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})
-@SuppressWarnings("unchecked")
-//By iterating over all repositories in the context, we can be sure that basic repository functionality isn't broken by any overriding methods
-public class AbstractJpaRepositoryTest {
-    @PersistenceContext
-    private EntityManager sharedManager;
-
-    @Autowired
-    private List<Repository> repositories;
-    //NOTE: In order for tests to succeed, there must be an object with id of 1 in the store for every repository
-    private static final Long VALID_ENTITY_ID = 1L;
-    private static final Long INVALID_ENTITY_ID = -1L;
-
-    @Test
-    public void getById_validId() {
-        for (Repository repository : repositories) {
-            BasicEntity entity = (BasicEntity)repository.get(VALID_ENTITY_ID);
-            assertThat(entity, is(notNullValue()));
-            assertThat(entity.getEntityId(), is(equalTo(VALID_ENTITY_ID)));
-        }
-    }
-
-    @Test
-    public void getById_invalidId() {
-        for (Repository repository : repositories) {
-            BasicEntity entity = (BasicEntity)repository.get(INVALID_ENTITY_ID);
-            assertThat(entity, is(nullValue()));
-        }
-    }
-
-    @Test
-    @Rollback(true)
-    public void save_newEntity() throws Exception {
-        for (Repository repository : repositories) {
-            BasicEntity entity = constructNewEntityForRepository(repository);
-            RepositoryTestUtils.populateAllRequiredFieldsInEntity(sharedManager, entity);
-            BasicEntity saved = (BasicEntity)repository.save(entity);
-            sharedManager.flush();
-            assertThat(saved, is(sameInstance(entity)));
-            assertThat(saved.getEntityId(), is(notNullValue()));
-        }
-    }
-
-    @Test
-    @Rollback(true)
-    public void save_existingEntity() {
-        for (Repository repository : repositories) {
-            BasicEntity entity = constructNewEntityForRepository(repository);
-            entity.setEntityId(VALID_ENTITY_ID);
-            BasicEntity saved = (BasicEntity)repository.save(entity);
-            sharedManager.flush();
-            assertThat(saved, is(not(sameInstance(entity))));
-            assertThat(saved.getEntityId(), is(equalTo(entity.getEntityId())));
-        }
-
-    }
-
-    @Test
-    @Rollback(true)
-    public void delete() throws Exception {
-        for(Repository repository : repositories) {
-            // to prevent possible RI errors lets create fresh objects then delete them
-            BasicEntity entity = constructNewEntityForRepository(repository);
-            RepositoryTestUtils.populateAllRequiredFieldsInEntity(sharedManager, entity);
-            BasicEntity saved = (BasicEntity)repository.save(entity);
-            long entityId = saved.getEntityId();
-            assertThat(entityId > 0, is(true));
-
-            repository.delete(saved);
-            sharedManager.flush();
-            assertThat(repository.get(entityId), is(nullValue()));
-        }
-    }
-
-    private BasicEntity constructNewEntityForRepository(Repository repository) {
-        try {
-            return (BasicEntity)repository.getType().newInstance();
-        } catch (Throwable e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaCategoryRepositoryTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaCategoryRepositoryTest.java
deleted file mode 100644
index 8a81982..0000000
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaCategoryRepositoryTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.repository.impl;

-

-import org.apache.openjpa.persistence.PersistenceException;

-import org.apache.rave.portal.model.Category;

-import org.apache.rave.portal.model.User;

-import org.apache.rave.portal.repository.CategoryRepository;

-import org.junit.Test;

-import org.junit.runner.RunWith;

-import org.springframework.beans.factory.annotation.Autowired;

-import org.springframework.test.annotation.Rollback;

-import org.springframework.test.context.ContextConfiguration;

-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

-import org.springframework.transaction.annotation.Transactional;

-

-import javax.persistence.EntityManager;

-import javax.persistence.PersistenceContext;

-import java.util.Date;

-import java.util.List;

-

-import static org.junit.Assert.*;

-import static org.hamcrest.CoreMatchers.*;

-

-@Transactional

-@RunWith(SpringJUnit4ClassRunner.class)

-@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

-

-public class JpaCategoryRepositoryTest {

-

-    @PersistenceContext

-    private EntityManager manager;

-

-    @Autowired

-    private CategoryRepository repository;

-

-    private static final String DUPLICATE_TEXT_VALUE = "Sample Category";

-

-    @Test

-    public void getAll() {

-        List<Category> list = repository.getAll();

-        assertThat(list.size(), is(4));

-        // verify proper sorting alphabetical by text attribute

-        String lastText = "";

-        for (Category wc : list) {

-            String currentText = wc.getText();

-            assertThat(currentText.compareTo(lastText) > 0, is(true));

-            lastText = currentText;

-        }

-    }

-

-    /**

-     * Verify that a unique constraint exception is thrown if a duplicate text value is attempted to be added

-     */

-    @Test

-    public void save_duplicateText_exception() {

-        Date now = new Date();

-        User user = new User(1L);

-

-        Category wc = new Category();

-        wc.setText(DUPLICATE_TEXT_VALUE);

-        wc.setCreatedDate(now);

-        wc.setCreatedUser(user);

-        wc.setLastModifiedDate(now);

-        wc.setLastModifiedUser(user);

-

-        boolean gotExpectedException = false;

-        try {

-            repository.save(wc);

-            manager.flush();

-        } catch (PersistenceException e) {

-            assertThat(e.getCause().toString().contains("Unique"), is(true));

-            gotExpectedException = true;

-        } finally {

-            if (!gotExpectedException) {

-                fail("Expected to get a PersistenceException due to Unique Constraint Violation");

-            }

-        }

-    }

-

-    @Test

-    @Rollback(value = true)

-    public void removeFromCreatedOrModifiedFields() {

-        assertThat(repository.removeFromCreatedOrModifiedFields(1L), is(3));

-    }

-}

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaTagRepositoryTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaTagRepositoryTest.java
deleted file mode 100644
index 065b6ef..0000000
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaTagRepositoryTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.repository.impl;

-

-import org.apache.rave.portal.model.Tag;

-import org.apache.rave.portal.repository.TagRepository;

-import org.junit.Test;

-import org.junit.runner.RunWith;

-import org.springframework.beans.factory.annotation.Autowired;

-import org.springframework.test.context.ContextConfiguration;

-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

-import org.springframework.transaction.annotation.Transactional;

-

-import javax.persistence.EntityManager;

-import javax.persistence.PersistenceContext;

-import java.util.List;

-

-import static org.junit.Assert.*;

-

-/**

- *

- */

-@Transactional

-@RunWith(SpringJUnit4ClassRunner.class)

-@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

-public class JpaTagRepositoryTest {

-

-    @PersistenceContext

-    private EntityManager manager;

-

-    @Autowired

-    private TagRepository repository;

-

-

-    private static final Long VALID_ID = 1L;

-

-    @Test

-    public void getById_validId() {

-        final Tag tag = repository.get(VALID_ID);

-        assertNotNull(tag);

-        assertEquals(VALID_ID, tag.getEntityId());

-        assertEquals(tag.getKeyword(), "news");

-    }

-

-    @Test

-    public void getList() {

-        List<Tag> list = repository.getAll();

-        assertTrue(list.size() == 2);

-        assertEquals(list.iterator().next().getKeyword(), "news");

-        assertTrue(list.iterator().next().getWidgets().size() == 1);

-    }

-

-    @Test

-    public void countAll() {

-        int count = repository.getCountAll();

-        assertTrue("Found at least 1 tag", count == 2);

-    }

-

-    @Test

-    public void getByKeyword() {

-        Tag tag = repository.getByKeyword("news");

-        assertNotNull(tag);

-        assertTrue(tag.getEntityId() == 1);

-        tag = repository.getByKeyword("NEWS");

-        assertNotNull(tag);

-        assertTrue(tag.getEntityId() == 1);

-        tag = repository.getByKeyword("news  ");

-        assertNotNull(tag);

-        assertTrue(tag.getEntityId() == 1);

-        tag = repository.getByKeyword("   news  ");

-        assertNotNull(tag);

-        assertTrue(tag.getEntityId() == 1);

-

-    }

-

-

-}

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepositoryTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepositoryTest.java
deleted file mode 100644
index 6a5966a..0000000
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepositoryTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one

- * or more contributor license agreements.  See the NOTICE file

- * distributed with this work for additional information

- * regarding copyright ownership.  The ASF licenses this file

- * to you 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.rave.portal.repository.impl;

-

-import org.apache.rave.portal.model.WidgetTag;

-import org.apache.rave.portal.repository.WidgetTagRepository;

-import org.junit.Test;

-import org.junit.runner.RunWith;

-import org.springframework.beans.factory.annotation.Autowired;

-import org.springframework.test.context.ContextConfiguration;

-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

-import org.springframework.transaction.annotation.Transactional;

-

-import javax.persistence.EntityManager;

-import javax.persistence.PersistenceContext;

-

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertNotNull;

-import static org.junit.Assert.assertTrue;

-

-/**

- *

- */

-@Transactional

-@RunWith(SpringJUnit4ClassRunner.class)

-@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

-public class JpaWidgetTagRepositoryTest {

-

-    @PersistenceContext

-    private EntityManager manager;

-

-    @Autowired

-    private WidgetTagRepository repository;

-

-    @Test

-    public void save() {

-

-

-    }

-

-}

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluatorTest.java
index cad82c2..3228d29 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultCategoryPermissionEvaluatorTest.java
@@ -18,7 +18,10 @@
  */

 package org.apache.rave.portal.security.impl;

 

-import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.Category;

+import org.apache.rave.portal.model.Widget;

+import org.apache.rave.portal.model.impl.CategoryImpl;

+import org.apache.rave.portal.model.impl.UserImpl;

 import org.apache.rave.portal.repository.CategoryRepository;

 import org.apache.rave.portal.security.ModelPermissionEvaluator;

 import org.apache.rave.portal.security.util.AuthenticationUtils;

@@ -42,7 +45,7 @@
     private CategoryRepository mockCategoryRepository;

 

     private Category category;

-    private User user, user2;

+    private UserImpl user, user2;

     private Authentication mockAuthentication;

     private List<GrantedAuthority> grantedAuthorities;

 

@@ -50,21 +53,21 @@
     private final Long VALID_USER_ID = 99L;

     private final String VALID_USERNAME = "john.doe";

     private final String VALID_USERNAME2 = "jane.doe";

-    

+

     @Before

     public void setUp() {

         mockCategoryRepository = createMock(CategoryRepository.class);

         defaultCategoryPermissionEvaluator = new DefaultCategoryPermissionEvaluator(mockCategoryRepository);

         mockAuthentication = createMock(Authentication.class);

 

-        user = new User();

+        user = new UserImpl();

         user.setUsername(VALID_USERNAME);

-        user.setEntityId(VALID_USER_ID);

-        user2 = new User();

+        user.setId(VALID_USER_ID);

+        user2 = new UserImpl();

         user2.setUsername(VALID_USERNAME2);

-        

-        category = new Category();

-        category.setEntityId(VALID_WIDGET_CATEGORY_ID);

+

+        category = new CategoryImpl();

+        category.setId(VALID_WIDGET_CATEGORY_ID);

         category.setCreatedUser(user);

 

         grantedAuthorities = new ArrayList<GrantedAuthority>();

@@ -142,7 +145,7 @@
         replay(mockAuthentication, mockCategoryRepository);

         assertThat(defaultCategoryPermissionEvaluator.hasPermission(mockAuthentication, category, ModelPermissionEvaluator.Permission.UPDATE), is(true));

         verify(mockAuthentication, mockCategoryRepository);

-    }     

+    }

 

     @Test

     public void testHasPermission_3args_read() {

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluatorTest.java
index 6fb8fdc..7adcafc 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultPagePermissionEvaluatorTest.java
@@ -21,7 +21,8 @@
 
 import org.apache.rave.portal.model.Page;
 import org.apache.rave.portal.model.PageType;
-import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.PageImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.repository.PageRepository;
 import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;
 import org.apache.rave.portal.security.util.AuthenticationUtils;
@@ -49,7 +50,7 @@
     private PageRepository mockPageRepository;
     private Authentication mockAuthentication;
     private Page page, personProfilePage, pageSubPage, personProfileSubPage;
-    private User user, user2;    
+    private UserImpl user, user2;
     private List<GrantedAuthority> grantedAuthoritiesList;
 
     private final Long VALID_USER_ID = 99L;
@@ -66,30 +67,30 @@
         mockAuthentication = createMock(Authentication.class);
 
         defaultPagePermissionEvaluator = new DefaultPagePermissionEvaluator(mockPageRepository);
-        
-        user = new User();
+
+        user = new UserImpl();
         user.setUsername(VALID_USERNAME);
-        user.setEntityId(VALID_USER_ID);
-        user2 = new User();
+        user.setId(VALID_USER_ID);
+        user2 = new UserImpl();
         user2.setUsername(VALID_USERNAME2);
 
-        page = new Page();
-        page.setEntityId(VALID_PAGE_ID);
+        page = new PageImpl();
+        page.setId(VALID_PAGE_ID);
         page.setOwner(user);
         page.setPageType(PageType.USER);
 
-        pageSubPage = new Page();
-        pageSubPage.setEntityId(VALID_PAGE_ID4);
+        pageSubPage = new PageImpl();
+        pageSubPage.setId(VALID_PAGE_ID4);
         pageSubPage.setOwner(user);
         pageSubPage.setPageType(PageType.SUB_PAGE);
         pageSubPage.setParentPage(page);
 
-        personProfilePage = new Page();
-        personProfilePage.setEntityId(VALID_PAGE_ID2);
+        personProfilePage = new PageImpl();
+        personProfilePage.setId(VALID_PAGE_ID2);
         personProfilePage.setOwner(user);
         personProfilePage.setPageType(PageType.PERSON_PROFILE);
-        personProfileSubPage = new Page();
-        personProfileSubPage.setEntityId(VALID_PAGE_ID3);
+        personProfileSubPage = new PageImpl();
+        personProfileSubPage.setId(VALID_PAGE_ID3);
         personProfileSubPage.setOwner(user);
         personProfileSubPage.setPageType(PageType.PERSON_PROFILE);
         personProfileSubPage.setParentPage(personProfilePage);
@@ -97,87 +98,87 @@
         grantedAuthoritiesList = new ArrayList<GrantedAuthority>();
         grantedAuthoritiesList.add(new SimpleGrantedAuthority("ROLE_USER"));
     }
- 
-   
+
+
     @Test
-    public void testGetType() throws ClassNotFoundException {            
+    public void testGetType() throws ClassNotFoundException {
         assertThat(defaultPagePermissionEvaluator.getType().getName(), is(Page.class.getName()));
     }
-  
+
     @Test
     public void testHasPermission_3args_administer() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        replay(mockAuthentication);              
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.ADMINISTER), is(false));        
+        replay(mockAuthentication);
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.ADMINISTER), is(false));
         verify(mockAuthentication);
     }
-    
+
     @Test
-    public void testHasPermission_3args_administer_hasAdminRole() {                             
+    public void testHasPermission_3args_administer_hasAdminRole() {
         grantedAuthoritiesList.add(new SimpleGrantedAuthority(AuthenticationUtils.ROLE_ADMIN));
 
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        replay(mockAuthentication);              
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.ADMINISTER), is(true));        
+        replay(mockAuthentication);
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.ADMINISTER), is(true));
         verify(mockAuthentication);
-    }    
-    
+    }
+
     @Test
     public void testHasPermission_3args_create_isPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
         expect(mockAuthentication.getPrincipal()).andReturn(user);
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication); 
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.CREATE), is(true));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.CREATE), is(true));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }    
-    
+    }
+
     @Test
     public void testHasPermission_3args_create_isNotPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication); 
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.CREATE), is(false));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.CREATE), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }       
-    
+    }
+
     @Test
     public void testHasPermission_3args_delete_isPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
         expect(mockAuthentication.getPrincipal()).andReturn(user);
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.DELETE), is(true));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.DELETE), is(true));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }        
-    
+    }
+
     @Test
     public void testHasPermission_3args_delete_notPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.DELETE), is(false));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.DELETE), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }       
-    
+    }
+
     @Test
     public void testHasPermission_3args_read_isPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
         expect(mockAuthentication.getPrincipal()).andReturn(user);
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.READ), is(true));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.READ), is(true));
         verify(mockAuthentication);
         verify(mockPageRepository);
     }
@@ -193,15 +194,15 @@
         verify(mockAuthentication);
         verify(mockPageRepository);
     }
-    
+
     @Test
     public void testHasPermission_3args_read_notPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.READ), is(false));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.READ), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
     }
@@ -209,7 +210,7 @@
     @Test
     public void testHasPermission_3args_read_notPageOwner_pageSubPage() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID4)).andReturn(pageSubPage);
         replay(mockAuthentication);
         replay(mockPageRepository);
@@ -253,79 +254,79 @@
     @Test
     public void testHasPermission_3args_update_notPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
         replay(mockAuthentication);
         replay(mockPageRepository);
         assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, page, Permission.UPDATE), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }         
-    
+    }
+
     @Test
     public void testHasPermission_4args_administer() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        replay(mockAuthentication);              
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.ADMINISTER), is(false));        
+        replay(mockAuthentication);
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.ADMINISTER), is(false));
         verify(mockAuthentication);
-    }    
-    
+    }
+
     @Test
     public void testHasPermission_4args_create_isPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
         expect(mockAuthentication.getPrincipal()).andReturn(user);
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
-        replay(mockPageRepository);     
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.CREATE), is(true));        
+        replay(mockAuthentication);
+        replay(mockPageRepository);
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.CREATE), is(true));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }     
-    
+    }
+
     @Test
     public void testHasPermission_4args_create_isNotPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
-        replay(mockPageRepository);     
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.CREATE), is(false));        
+        replay(mockAuthentication);
+        replay(mockPageRepository);
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.CREATE), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }         
-    
+    }
+
     @Test
     public void testHasPermission_4args_delete_isPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
         expect(mockAuthentication.getPrincipal()).andReturn(user);
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.DELETE), is(true));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.DELETE), is(true));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }        
-        
+    }
+
     @Test
     public void testHasPermission_4args_delete_notPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.DELETE), is(false));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.DELETE), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }       
-    
+    }
+
     @Test
     public void testHasPermission_4args_read_isPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
         expect(mockAuthentication.getPrincipal()).andReturn(user);
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.READ), is(true));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.READ), is(true));
         verify(mockAuthentication);
         verify(mockPageRepository);
     }
@@ -341,15 +342,15 @@
         verify(mockAuthentication);
         verify(mockPageRepository);
     }
-    
+
     @Test
     public void testHasPermission_4args_read_notPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.READ), is(false));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.READ), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
     }
@@ -357,7 +358,7 @@
     @Test
     public void testHasPermission_4args_read_notPageOwner_pageSubPage() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID4)).andReturn(page);
         replay(mockAuthentication);
         replay(mockPageRepository);
@@ -393,52 +394,52 @@
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
         expect(mockAuthentication.getPrincipal()).andReturn(user);
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.UPDATE), is(true));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.UPDATE), is(true));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }   
-    
+    }
+
     @Test
     public void testHasPermission_4args_update_notPageOwner() {
         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);
-        expect(mockAuthentication.getPrincipal()).andReturn(user2);
+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();
         expect(mockPageRepository.get(VALID_PAGE_ID)).andReturn(page);
-        replay(mockAuthentication);      
+        replay(mockAuthentication);
         replay(mockPageRepository);
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.UPDATE), is(false));        
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, VALID_PAGE_ID, Page.class.getName(), Permission.UPDATE), is(false));
         verify(mockAuthentication);
         verify(mockPageRepository);
-    }         
-    
+    }
+
     @Test
-    public void testHasPermission_4args_update_isPageOwner_withRaveSecurityContextObject() {                             
+    public void testHasPermission_4args_update_isPageOwner_withRaveSecurityContextObject() {
         RaveSecurityContext raveSecurityContext = new RaveSecurityContext(VALID_USER_ID, "org.apache.rave.portal.model.User");
-                
+
         expect(mockAuthentication.getPrincipal()).andReturn(user);
-        replay(mockAuthentication);      
-        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, Page.class.getName(), Permission.UPDATE), is(true));        
+        replay(mockAuthentication);
+        assertThat(defaultPagePermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, Page.class.getName(), Permission.UPDATE), is(true));
         verify(mockAuthentication);
-    } 
-    
+    }
+
     @Test(expected=IllegalArgumentException.class)
-    public void testHasPermission_4args_update_isPageOwner_withInvalidRaveSecurityContextType() {                             
+    public void testHasPermission_4args_update_isPageOwner_withInvalidRaveSecurityContextType() {
         RaveSecurityContext raveSecurityContext = new RaveSecurityContext(VALID_USER_ID, "java.lang.String");
-                
+
         expect(mockAuthentication.getPrincipal()).andReturn(user);
-        replay(mockAuthentication);      
-        defaultPagePermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, Page.class.getName(), Permission.UPDATE);        
+        replay(mockAuthentication);
+        defaultPagePermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, Page.class.getName(), Permission.UPDATE);
         verify(mockAuthentication);
-    }    
-    
+    }
+
     @Test(expected=IllegalArgumentException.class)
-    public void testHasPermission_4args_update_isPageOwner_withUnknownRaveSecurityContextType() {                             
+    public void testHasPermission_4args_update_isPageOwner_withUnknownRaveSecurityContextType() {
         RaveSecurityContext raveSecurityContext = new RaveSecurityContext(VALID_USER_ID, "foo.bar.DummyClass");
-                
+
         expect(mockAuthentication.getPrincipal()).andReturn(user);
-        replay(mockAuthentication);      
-        defaultPagePermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, Page.class.getName(), Permission.UPDATE);        
+        replay(mockAuthentication);
+        defaultPagePermissionEvaluator.hasPermission(mockAuthentication, raveSecurityContext, Page.class.getName(), Permission.UPDATE);
         verify(mockAuthentication);
-    }    
+    }
 }
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluatorTest.java
index 449ae6f..10f7d72 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionPermissionEvaluatorTest.java
@@ -20,7 +20,9 @@
 

 import org.apache.rave.portal.model.Page;

 import org.apache.rave.portal.model.Region;

-import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.impl.PageImpl;

+import org.apache.rave.portal.model.impl.RegionImpl;

+import org.apache.rave.portal.model.impl.UserImpl;

 import org.apache.rave.portal.repository.RegionRepository;

 import org.apache.rave.portal.security.ModelPermissionEvaluator;

 import org.apache.rave.portal.security.util.AuthenticationUtils;

@@ -44,7 +46,7 @@
     private RegionRepository mockRegionRepository;

     private Page page;

     private Region region, region2;

-    private User user, user2;

+    private UserImpl user, user2;

     private Authentication mockAuthentication;

     private List<GrantedAuthority> grantedAuthoritiesList;

 

@@ -60,16 +62,16 @@
         defaultRegionPermissionEvaluator = new DefaultRegionPermissionEvaluator(mockRegionRepository);

         mockAuthentication = createMock(Authentication.class);

 

-        user = new User();

+        user = new UserImpl();

         user.setUsername(VALID_USERNAME);

-        user.setEntityId(VALID_USER_ID);

-        user2 = new User();

+        user.setId(VALID_USER_ID);

+        user2 = new UserImpl();

         user2.setUsername(VALID_USERNAME2);

-        page = new Page();

-        page.setEntityId(VALID_PAGE_ID);

+        page = new PageImpl();

+        page.setId(VALID_PAGE_ID);

         page.setOwner(user);

-        region = new Region();

-        region.setEntityId(VALID_REGION_ID);

+        region = new RegionImpl();

+        region.setId(VALID_REGION_ID);

         region.setPage(page);

         grantedAuthoritiesList = new ArrayList<GrantedAuthority>();

         grantedAuthoritiesList.add(new SimpleGrantedAuthority("ROLE_USER"));

@@ -112,7 +114,7 @@
     @Test

     public void testHasPermission_3args_create_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

@@ -136,7 +138,7 @@
     @Test

     public void testHasPermission_3args_delete_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

@@ -160,7 +162,7 @@
     @Test

     public void testHasPermission_3args_update_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

@@ -184,7 +186,7 @@
     @Test

     public void testHasPermission_3args_read_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

@@ -216,7 +218,7 @@
     @Test

     public void testHasPermission_4args_create_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

@@ -240,7 +242,7 @@
     @Test

     public void testHasPermission_4args_delete_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

@@ -264,7 +266,7 @@
     @Test

     public void testHasPermission_4args_read_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

@@ -288,7 +290,7 @@
     @Test

     public void testHasPermission_4args_update_isNotRegionOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionRepository.get(VALID_REGION_ID)).andReturn(region);

         replay(mockAuthentication);

         replay(mockRegionRepository);

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java
index 678d038..9f671d4 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultRegionWidgetPermissionEvaluatorTest.java
@@ -21,7 +21,10 @@
 import org.apache.rave.portal.model.Page;

 import org.apache.rave.portal.model.Region;

 import org.apache.rave.portal.model.RegionWidget;

-import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.impl.PageImpl;

+import org.apache.rave.portal.model.impl.RegionImpl;

+import org.apache.rave.portal.model.impl.RegionWidgetImpl;

+import org.apache.rave.portal.model.impl.UserImpl;

 import org.apache.rave.portal.repository.RegionWidgetRepository;

 import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;

 import org.apache.rave.portal.security.util.AuthenticationUtils;

@@ -47,7 +50,7 @@
     private Page page;

     private RegionWidget regionWidget;

     private Region region;

-    private User user, user2;

+    private UserImpl user, user2;

     private List<GrantedAuthority> grantedAuthoritiesList;

 

     private final Long VALID_REGION_ID = 1L;

@@ -63,19 +66,19 @@
         defaultRegionWidgetPermissionEvaluator = new DefaultRegionWidgetPermissionEvaluator(mockRegionWidgetRepository);

         mockAuthentication = createMock(Authentication.class);

 

-        user = new User();

+        user = new UserImpl();

         user.setUsername(VALID_USERNAME);

-        user.setEntityId(VALID_USER_ID);

-        user2 = new User();

+        user.setId(VALID_USER_ID);

+        user2 = new UserImpl();

         user2.setUsername(VALID_USERNAME2);

-        page = new Page();

-        page.setEntityId(VALID_PAGE_ID);

+        page = new PageImpl();

+        page.setId(VALID_PAGE_ID);

         page.setOwner(user);

-        region = new Region();

-        region.setEntityId(VALID_REGION_ID);

+        region = new RegionImpl();

+        region.setId(VALID_REGION_ID);

         region.setPage(page);

-        regionWidget = new RegionWidget();

-        regionWidget.setEntityId(VALID_REGION_WIDGET_ID);

+        regionWidget = new RegionWidgetImpl();

+        regionWidget.setId(VALID_REGION_WIDGET_ID);

         regionWidget.setRegion(region);

         grantedAuthoritiesList = new ArrayList<GrantedAuthority>();

         grantedAuthoritiesList.add(new SimpleGrantedAuthority("ROLE_USER"));

@@ -118,7 +121,7 @@
     @Test

     public void testHasPermission_3args_create_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

@@ -142,7 +145,7 @@
     @Test

     public void testHasPermission_3args_delete_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

@@ -166,7 +169,7 @@
     @Test

     public void testHasPermission_3args_update_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

@@ -190,7 +193,7 @@
     @Test

     public void testHasPermission_3args_read_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

@@ -222,7 +225,7 @@
     @Test

     public void testHasPermission_4args_create_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

@@ -246,7 +249,7 @@
     @Test

     public void testHasPermission_4args_delete_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

@@ -270,7 +273,7 @@
     @Test

     public void testHasPermission_4args_read_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

@@ -294,7 +297,7 @@
     @Test

     public void testHasPermission_4args_update_isNotRegionWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

-        expect(mockAuthentication.getPrincipal()).andReturn(user2);

+        expect(mockAuthentication.getPrincipal()).andReturn(user2).anyTimes();

         expect(mockRegionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);

         replay(mockAuthentication);

         replay(mockRegionWidgetRepository);

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluatorTest.java
index c656440..84ee45b 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetCommentPermissionEvaluatorTest.java
@@ -15,8 +15,9 @@
  */
 package org.apache.rave.portal.security.impl;
 
-import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.model.WidgetComment;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.apache.rave.portal.model.impl.WidgetCommentImpl;
 import org.apache.rave.portal.repository.WidgetCommentRepository;
 import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;
 import org.apache.rave.portal.security.util.AuthenticationUtils;
@@ -44,7 +45,7 @@
     private WidgetCommentRepository mockWidgetCommentRepository;
     private Authentication mockAuthentication;
     private WidgetComment widgetComment;
-    private User user, user2;
+    private UserImpl user, user2;
     private List<GrantedAuthority> grantedAuthoritiesList;
 
     private final Long VALID_COMMENT_ID = 3L;
@@ -59,14 +60,14 @@
         mockAuthentication = createMock(Authentication.class);
         defaultWidgetCommentPermissionEvaluator = new DefaultWidgetCommentPermissionEvaluator(mockWidgetCommentRepository);
 
-        user = new User();
+        user = new UserImpl();
         user.setUsername(VALID_USERNAME);
-        user.setEntityId(VALID_USER_ID);
-        user2 = new User();
+        user.setId(VALID_USER_ID);
+        user2 = new UserImpl();
         user2.setUsername(VALID_USERNAME2);
-        user2.setEntityId(INVALID_USER_ID);
-        widgetComment = new WidgetComment();
-        widgetComment.setEntityId(VALID_COMMENT_ID);
+        user2.setId(INVALID_USER_ID);
+        widgetComment = new WidgetCommentImpl();
+        widgetComment.setId(VALID_COMMENT_ID);
         widgetComment.setUser(user);
         grantedAuthoritiesList = new ArrayList<GrantedAuthority>();
         grantedAuthoritiesList.add(new SimpleGrantedAuthority("ROLE_USER"));
@@ -223,9 +224,9 @@
         expect(mockAuthentication.getPrincipal()).andReturn(user).anyTimes();
         replay(mockAuthentication);
 
-        WidgetComment localWidgetComment = new WidgetComment();
-        User localUser = new User();
-        localUser.setEntityId(VALID_USER_ID);
+        WidgetComment localWidgetComment = new WidgetCommentImpl();
+        UserImpl localUser = new UserImpl();
+        localUser.setId(VALID_USER_ID);
         localWidgetComment.setUser(localUser);
         expect(mockWidgetCommentRepository.get(VALID_COMMENT_ID)).andReturn(localWidgetComment).anyTimes();
         replay(mockWidgetCommentRepository);
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluatorTest.java
index 5903ab2..e4bdf6e 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetPermissionEvaluatorTest.java
@@ -20,7 +20,10 @@
 

 import org.apache.rave.portal.model.Page;

 import org.apache.rave.portal.model.Widget;

-import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.WidgetStatus;

+import org.apache.rave.portal.model.impl.PageImpl;

+import org.apache.rave.portal.model.impl.UserImpl;

+import org.apache.rave.portal.model.impl.WidgetImpl;

 import org.apache.rave.portal.repository.WidgetRepository;

 import org.apache.rave.portal.security.ModelPermissionEvaluator;

 import org.apache.rave.portal.security.util.AuthenticationUtils;

@@ -35,7 +38,6 @@
 import java.util.Collection;

 import java.util.List;

 

-import org.apache.rave.portal.model.WidgetStatus;

 import static org.easymock.EasyMock.*;

 import static org.hamcrest.CoreMatchers.is;

 import static org.junit.Assert.assertThat;

@@ -45,11 +47,11 @@
     private WidgetRepository mockWidgetRepository;

     private Page page;

     private Widget widget, widget2;

-    private User user, user2;

+    private UserImpl user, user2;

     private Authentication mockAuthentication;

     private List<GrantedAuthority> grantedAuthoritiesList;

 

-    private final Long VALID_REGION_ID = 1L;

+    private final Long VALID_WIDGET_ID = 1L;

     private final Long VALID_PAGE_ID = 3L;

     private final Long VALID_USER_ID = 99L;

     private final String VALID_USERNAME = "john.doe";

@@ -61,16 +63,15 @@
         defaultWidgetPermissionEvaluator = new DefaultWidgetPermissionEvaluator(mockWidgetRepository);

         mockAuthentication = createMock(Authentication.class);

 

-        user = new User();

+        user = new UserImpl();

         user.setUsername(VALID_USERNAME);

-        user.setEntityId(VALID_USER_ID);

-        user2 = new User();

+        user.setId(VALID_USER_ID);

+        user2 = new UserImpl();

         user2.setUsername(VALID_USERNAME2);

-        page = new Page();

-        page.setEntityId(VALID_PAGE_ID);

+        page = new PageImpl();

+        page.setId(VALID_PAGE_ID);

         page.setOwner(user);

-        widget = new Widget();

-        widget.setEntityId(VALID_REGION_ID);

+        widget = new WidgetImpl(VALID_WIDGET_ID);

         widget.setOwner(user);

         widget.setWidgetStatus(WidgetStatus.PUBLISHED);

         grantedAuthoritiesList = new ArrayList<GrantedAuthority>();

@@ -103,7 +104,7 @@
     public void testHasPermission_3args_create_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.CREATE), is(true));

@@ -115,7 +116,7 @@
     public void testHasPermission_3args_create_isNotWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.CREATE), is(false));

@@ -127,7 +128,7 @@
     public void testHasPermission_3args_delete_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.DELETE), is(true));

@@ -139,7 +140,7 @@
     public void testHasPermission_3args_delete_isNotWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.DELETE), is(false));

@@ -151,7 +152,7 @@
     public void testHasPermission_3args_update_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.UPDATE), is(true));

@@ -163,19 +164,19 @@
     public void testHasPermission_3args_update_isNotWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.UPDATE), is(false));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

-    }     

+    }

 

     @Test

     public void testHasPermission_3args_read_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.READ), is(true));

@@ -187,7 +188,7 @@
     public void testHasPermission_3args_read_isNotWidgetOwner_isPublishedGadget() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.READ), is(true));

@@ -201,19 +202,19 @@
 

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

         assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, widget, ModelPermissionEvaluator.Permission.READ), is(false));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

-    }    

-    

+    }

+

     @Test

     public void testHasPermission_4args_administer() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         replay(mockAuthentication);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.ADMINISTER), is(false));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.ADMINISTER), is(false));

         verify(mockAuthentication);

     }

 

@@ -221,10 +222,10 @@
     public void testHasPermission_4args_create_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

@@ -233,10 +234,10 @@
     public void testHasPermission_4args_create_isNotWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

@@ -245,10 +246,10 @@
     public void testHasPermission_4args_delete_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

@@ -257,10 +258,10 @@
     public void testHasPermission_4args_delete_isNotWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

@@ -269,10 +270,10 @@
     public void testHasPermission_4args_read_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

@@ -281,10 +282,10 @@
     public void testHasPermission_4args_read_isNotWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

@@ -293,10 +294,10 @@
     public void testHasPermission_4args_update_isWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(true));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

@@ -305,10 +306,10 @@
     public void testHasPermission_4args_update_isNotWidgetOwner() {

         EasyMock.<Collection<? extends GrantedAuthority>>expect(mockAuthentication.getAuthorities()).andReturn(grantedAuthoritiesList);

         expect(mockAuthentication.getPrincipal()).andReturn(user2);

-        expect(mockWidgetRepository.get(VALID_REGION_ID)).andReturn(widget);

+        expect(mockWidgetRepository.get(VALID_WIDGET_ID)).andReturn(widget);

         replay(mockAuthentication);

         replay(mockWidgetRepository);

-        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_REGION_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

+        assertThat(defaultWidgetPermissionEvaluator.hasPermission(mockAuthentication, VALID_WIDGET_ID, Widget.class.getName(), ModelPermissionEvaluator.Permission.CREATE), is(false));

         verify(mockAuthentication);

         verify(mockWidgetRepository);

     }

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluatorTest.java
index d9cbfc2..abc4c9f 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/DefaultWidgetRatingPermissionEvaluatorTest.java
@@ -18,8 +18,9 @@
  */

 package org.apache.rave.portal.security.impl;

 

-import org.apache.rave.portal.model.User;

 import org.apache.rave.portal.model.WidgetRating;

+import org.apache.rave.portal.model.impl.UserImpl;

+import org.apache.rave.portal.model.impl.WidgetRatingImpl;

 import org.apache.rave.portal.repository.WidgetRatingRepository;

 import org.apache.rave.portal.security.ModelPermissionEvaluator;

 import org.apache.rave.portal.security.util.AuthenticationUtils;

@@ -45,7 +46,7 @@
     private Authentication mockAuthentication;

     private List<GrantedAuthority> grantedAuthoritiesList;

     private WidgetRating widgetRating;

-    private User user, user2;

+    private UserImpl user, user2;

 

     private final Long VALID_USER_ID = 99L;

     private final Long VALID_USER_ID2 = 100L;

@@ -59,16 +60,16 @@
         mockWidgetRatingRepository = createMock(WidgetRatingRepository.class);

         defaultWidgetRatingPermissionEvaluator = new DefaultWidgetRatingPermissionEvaluator(mockWidgetRatingRepository);

 

-        widgetRating = new WidgetRating();

+        widgetRating = new WidgetRatingImpl();

         widgetRating.setUserId(VALID_USER_ID);

         widgetRating.setWidgetId(VALID_WIDGET_ID);

-        widgetRating.setEntityId(VALID_WIDGET_ID);

+        widgetRating.setId(VALID_WIDGET_ID);

 

-        user = new User();

+        user = new UserImpl();

         user.setUsername(VALID_USERNAME);

-        user.setEntityId(VALID_USER_ID);

-        user2 = new User();

-        user2.setEntityId(VALID_USER_ID2);

+        user.setId(VALID_USER_ID);

+        user2 = new UserImpl();

+        user2.setId(VALID_USER_ID2);

         user2.setUsername(VALID_USERNAME2);

 

         mockAuthentication = createMock(Authentication.class);

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/RavePermissionEvaluatorTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/RavePermissionEvaluatorTest.java
index 062e309..4c4efa4 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/RavePermissionEvaluatorTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/security/impl/RavePermissionEvaluatorTest.java
@@ -19,17 +19,20 @@
 package org.apache.rave.portal.security.impl;
 
 import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.security.ModelPermissionEvaluator;
+import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.springframework.security.core.Authentication;
+
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.rave.portal.security.ModelPermissionEvaluator;
-import org.apache.rave.portal.security.ModelPermissionEvaluator.Permission;
-import org.springframework.security.core.Authentication;
-import org.junit.Before;
-import org.junit.Test;
-import static org.junit.Assert.*;
+
 import static org.easymock.EasyMock.*;
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
 
 /**
  *
@@ -40,89 +43,104 @@
     private Authentication authentication;
     private BasicEntityModel basicEntityModel;
     private NonBasicEntityModel nonBasicEntityModel;
-    
+
     private String READ_PERMISSION = "read";
     private String CREATE_OR_UPDATE_PERMISSION = "create_or_update";
     private Long VALID_BASIC_ENTITY_MODEL_ID = 4L;
-    
-    
+
     @Before
     public void setUp() {
         List<ModelPermissionEvaluator<?>> modelPermissionEvaluatorList = new ArrayList<ModelPermissionEvaluator<?>>();
-        modelPermissionEvaluatorList.add(new BasicEntityModelPermissionEvaluator());                       
-        modelPermissionEvaluatorList.add(new NonBasicEntityModelPermissionEvaluator());                   
+        modelPermissionEvaluatorList.add(new BasicEntityModelPermissionEvaluator());
+        modelPermissionEvaluatorList.add(new NonBasicEntityModelPermissionEvaluator());
+        modelPermissionEvaluatorList.add(new TestModelPermissionEvaluator());
         ravePermissionEvaluator = new RavePermissionEvaluator(modelPermissionEvaluatorList);
-        
+
         authentication = createMock(Authentication.class);
-        basicEntityModel = new BasicEntityModel(VALID_BASIC_ENTITY_MODEL_ID);        
+        basicEntityModel = new BasicEntityModel(VALID_BASIC_ENTITY_MODEL_ID);
         nonBasicEntityModel = new NonBasicEntityModel();
     }
-    
+
     @Test
     public void testLoadOrderOverride() {
         @SuppressWarnings("unchecked")
         ModelPermissionEvaluator<BasicEntityModel> mockedOverriddenPermissionEvaluator = createMock(ModelPermissionEvaluator.class);
         expect(mockedOverriddenPermissionEvaluator.getType()).andReturn(BasicEntityModel.class);
         expect(mockedOverriddenPermissionEvaluator.getLoadOrder()).andReturn(2);
-        expect(mockedOverriddenPermissionEvaluator.hasPermission(authentication, basicEntityModel, Permission.fromString(READ_PERMISSION))).andReturn(true);        
+        expect(mockedOverriddenPermissionEvaluator.hasPermission(authentication, basicEntityModel, Permission.fromString(READ_PERMISSION))).andReturn(true);
         replay(mockedOverriddenPermissionEvaluator);
-        
+
          List<ModelPermissionEvaluator<?>> modelPermissionEvaluatorList = new ArrayList<ModelPermissionEvaluator<?>>();
         // note we are adding the override instance first to verify the Collections.sort works as expected
         modelPermissionEvaluatorList.add(mockedOverriddenPermissionEvaluator);
-        modelPermissionEvaluatorList.add(new BasicEntityModelPermissionEvaluator());                       
+        modelPermissionEvaluatorList.add(new BasicEntityModelPermissionEvaluator());
         ravePermissionEvaluator = new RavePermissionEvaluator(modelPermissionEvaluatorList);
-        
-        assertThat(ravePermissionEvaluator.hasPermission(authentication, basicEntityModel, READ_PERMISSION), is(true));        
-        verify(mockedOverriddenPermissionEvaluator);    
+
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, basicEntityModel, READ_PERMISSION), is(true));
+        verify(mockedOverriddenPermissionEvaluator);
     }
-    
+
     @Test
-    public void testHasPermission_3args_read() {        
-        assertThat(ravePermissionEvaluator.hasPermission(authentication, basicEntityModel, READ_PERMISSION), is(true));        
+    public void testHasPermission_3args_read() {
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, basicEntityModel, READ_PERMISSION), is(true));
     }
-    
+
     @Test
-    public void testHasPermission_3args_createOrUpdate_nullEntityId() {        
-        assertThat(ravePermissionEvaluator.hasPermission(authentication, new BasicEntityModel(), CREATE_OR_UPDATE_PERMISSION), is(true));        
-    }    
-    
+    public void testHasPermission_3args_createOrUpdate_nullEntityId() {
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, new BasicEntityModel(), CREATE_OR_UPDATE_PERMISSION), is(true));
+    }
+
     @Test
-    public void testHasPermission_3args_createOrUpdate_populatedEntityId() {        
-        assertThat(ravePermissionEvaluator.hasPermission(authentication, basicEntityModel, CREATE_OR_UPDATE_PERMISSION), is(true));        
-    }     
-    
+    public void testHasPermission_3args_createOrUpdate_populatedEntityId() {
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, basicEntityModel, CREATE_OR_UPDATE_PERMISSION), is(true));
+    }
+
+    @Ignore
     @Test(expected=IllegalArgumentException.class)
-    public void testHasPermission_3args_createOrUpdate_nonBasicEntityModel() {        
+    public void testHasPermission_3args_createOrUpdate_nonBasicEntityModel() {
         ravePermissionEvaluator.hasPermission(authentication, nonBasicEntityModel, CREATE_OR_UPDATE_PERMISSION);
-    }     
-    
-    @Test
-    public void testHasPermission_3args_nullModel() {        
-        assertThat(ravePermissionEvaluator.hasPermission(authentication, null, READ_PERMISSION), is(false));        
     }
-    
-    @Test(expected=IllegalArgumentException.class)
-    public void testHasPermission_3args_invalidEvaluator() {        
-        List<String> list = new ArrayList<String>();
-        assertThat(ravePermissionEvaluator.hasPermission(authentication, list, READ_PERMISSION), is(true));        
-    }    
-    
+
     @Test
-    public void testHasPermission_4args() {    
-        assertThat(ravePermissionEvaluator.hasPermission(authentication, VALID_BASIC_ENTITY_MODEL_ID, BasicEntityModel.class.getName(), READ_PERMISSION), is(true));        
+    public void testHasPermission_3args_nullModel() {
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, null, READ_PERMISSION), is(false));
     }
 
     @Test(expected=IllegalArgumentException.class)
-    public void testHasPermission_4args_createOrUpdatePermission() {    
+    public void testHasPermission_3args_invalidEvaluator() {
+        List<String> list = new ArrayList<String>();
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, list, READ_PERMISSION), is(true));
+    }
+
+    @Test
+    public void testHasPermission_4args() {
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, VALID_BASIC_ENTITY_MODEL_ID, BasicEntityModel.class.getName(), READ_PERMISSION), is(true));
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testHasPermission_4args_createOrUpdatePermission() {
         ravePermissionEvaluator.hasPermission(authentication, VALID_BASIC_ENTITY_MODEL_ID, BasicEntityModel.class.getName(), CREATE_OR_UPDATE_PERMISSION);
-    }    
-    
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testHasPermission_4args_invalidClass() {
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, VALID_BASIC_ENTITY_MODEL_ID, "badclass", READ_PERMISSION), is(true));
+    }
+
+    @Test
+    public void testFindAndRegisterCompatibleMPE() {
+        assertThat(ravePermissionEvaluator.hasPermission(authentication, new TestModelImpl(), READ_PERMISSION), is(true));
+    }
+
+    interface TestModel {};
+
+    class TestModelImpl implements TestModel {}
+
     class BasicEntityModel implements BasicEntity {
         private Long entityId;
-        
+
         public BasicEntityModel() { }
-        
+
         public BasicEntityModel(Long entityId) {
             this.entityId = entityId;
         }
@@ -137,7 +155,7 @@
             this.entityId = entityId;
         }
     }
-    
+
     class BasicEntityModelPermissionEvaluator extends AbstractModelPermissionEvaluator<BasicEntityModel> {
         @Override
         public Class<BasicEntityModel> getType() {
@@ -148,17 +166,17 @@
         public boolean hasPermission(Authentication authentication, BasicEntityModel basicEntityModel, Permission permission) {
             return true;
         }
-        
+
         @Override
         public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Permission permission) {
             return true;
         }
-    }       
-    
-    class NonBasicEntityModel {            
-        public NonBasicEntityModel() { }                
     }
-    
+
+    class NonBasicEntityModel {
+        public NonBasicEntityModel() { }
+    }
+
     class NonBasicEntityModelPermissionEvaluator extends AbstractModelPermissionEvaluator<NonBasicEntityModel> {
         @Override
         public Class<NonBasicEntityModel> getType() {
@@ -169,10 +187,28 @@
         public boolean hasPermission(Authentication authentication, NonBasicEntityModel nonBasicEntityModel, Permission permission) {
             return true;
         }
-        
+
         @Override
         public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Permission permission) {
             return true;
         }
-    }           
+    }
+
+    class TestModelPermissionEvaluator extends AbstractModelPermissionEvaluator<TestModel> {
+        @Override
+        public Class<TestModel> getType() {
+            return TestModel.class;
+        }
+
+        @Override
+        public boolean hasPermission(Authentication authentication, TestModel testModel, Permission permission) {
+            return true;
+        }
+
+        @Override
+        public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Permission permission) {
+            return true;
+        }
+    }
+
 }
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultAuthorityServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultAuthorityServiceTest.java
index a664111..a7331d9 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultAuthorityServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultAuthorityServiceTest.java
@@ -20,20 +20,19 @@
 package org.apache.rave.portal.service.impl;
 
 import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.impl.AuthorityImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.repository.AuthorityRepository;
-import org.apache.rave.portal.service.impl.DefaultAuthorityService;
+import org.apache.rave.portal.service.AuthorityService;
 import org.junit.Before;
 import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.rave.portal.service.AuthorityService;
 import static org.easymock.EasyMock.*;
-
+import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
 
 /**
 Test for {@link org.apache.rave.portal.service.impl.DefaultAuthorityService}
@@ -75,19 +74,17 @@
     }
 
     private static Authority createAuthority() {
-        Authority authority = new Authority();
+        AuthorityImpl authority = new AuthorityImpl();
         authority.setAuthority("FOO");
         final long entityId = 123L;
-        authority.setEntityId(entityId);
         return authority;
     }
 
     @Test
     public void getAuthorityById_NotFound() {
-        Authority authority = new Authority();
+        AuthorityImpl authority = new AuthorityImpl();
         authority.setAuthority("BAR");
         final long entityId = 456L;
-        authority.setEntityId(entityId);
 
         expect(repository.get(entityId)).andReturn(null);
         replay(repository);
@@ -100,9 +97,9 @@
     @Test
     public void allAuthorities() {
         List<Authority> authorities = new ArrayList<Authority>();
-        Authority foo = new Authority();
+        Authority foo = new AuthorityImpl();
         foo.setAuthority("FOO");
-        Authority bar = new Authority();
+        Authority bar = new AuthorityImpl();
         bar.setAuthority("BAR");
         authorities.add(foo);
         authorities.add(bar);
@@ -120,10 +117,10 @@
     @Test
     public void test_getAllDefault() {
         List<Authority> authorities = new ArrayList<Authority>();
-        Authority foo = new Authority();
+        Authority foo = new AuthorityImpl();
         foo.setAuthority("FOO");
         foo.setDefaultForNewUser(true);
-        Authority bar = new Authority();
+        Authority bar = new AuthorityImpl();
         bar.setAuthority("BAR");
         bar.setDefaultForNewUser(true);
         
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultCategoryServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultCategoryServiceTest.java
index 57dddd5..b12f504 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultCategoryServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultCategoryServiceTest.java
@@ -21,6 +21,8 @@
 

 import org.apache.rave.portal.model.Category;

 import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.impl.CategoryImpl;

+import org.apache.rave.portal.model.impl.UserImpl;

 import org.apache.rave.portal.repository.CategoryRepository;

 import org.apache.rave.portal.service.CategoryService;

 import org.junit.Before;

@@ -31,8 +33,8 @@
 import java.util.List;

 

 import static org.easymock.EasyMock.*;

-import static org.junit.Assert.*;

 import static org.hamcrest.CoreMatchers.*;

+import static org.junit.Assert.assertThat;

 

 /**

  * Test for {@link org.apache.rave.portal.service.impl.DefaultCategoryService}

@@ -40,7 +42,7 @@
 public class DefaultCategoryServiceTest {

     private CategoryService service;

     private CategoryRepository repository;

-    

+

     private final Long VALID_ID = 4L;

     private final String VALID_TEXT = "category1";

     private final Date VALID_CREATED_DATE = new Date(66666666);

@@ -48,7 +50,7 @@
     private final Long VALID_CREATED_USER_ID = 77L;

     private final Long VALID_LAST_MODIFIED_USER_ID = 88L;

     private User validCreatedUser;

-    private User validLastModifiedUser;    

+    private User validLastModifiedUser;

     private Category validCategory;

 

     private final Long INVALID_ID = -999L;

@@ -58,11 +60,11 @@
         repository = createMock(CategoryRepository.class);

         service = new DefaultCategoryService(repository);

 

-        validCreatedUser = new User(VALID_CREATED_USER_ID);

-        validLastModifiedUser = new User(VALID_LAST_MODIFIED_USER_ID);

-        

-        validCategory = new Category();

-        validCategory.setEntityId(VALID_ID);

+        validCreatedUser = new UserImpl(VALID_CREATED_USER_ID);

+        validLastModifiedUser = new UserImpl(VALID_LAST_MODIFIED_USER_ID);

+

+        validCategory = new CategoryImpl();

+        validCategory.setId(VALID_ID);

         validCategory.setText(VALID_TEXT);

         validCategory.setCreatedUser(validCreatedUser);

         validCategory.setCreatedDate(VALID_CREATED_DATE);

@@ -90,19 +92,19 @@
     public void getAll() {

         List<Category> list = new ArrayList<Category>();

         list.add(validCategory);

-        list.add(new Category());

-        list.add(new Category());

+        list.add(new CategoryImpl());

+        list.add(new CategoryImpl());

 

         expect(repository.getAll()).andReturn(list);

         replay(repository);

         assertThat(service.getAll(), is(list));

-        verify(repository);        

+        verify(repository);

     }

 

     @Test

     public void create() {

         final String NEW_CATEGORY_TEXT = "new category";

-        Category expectedCategory = new Category();

+        Category expectedCategory = new CategoryImpl();

         expectedCategory.setText(NEW_CATEGORY_TEXT);

 

         expect(repository.save(expectedCategory)).andReturn(expectedCategory);

@@ -114,7 +116,7 @@
         assertThat(wc.getCreatedDate(), is(wc.getLastModifiedDate()));

         assertThat(wc.getCreatedUser(), is(validCreatedUser));

         assertThat(wc.getLastModifiedUser(), is(validCreatedUser));

-        

+

         verify(repository);

     }

 

@@ -122,8 +124,8 @@
     public void update() {

         final String UPDATED_TEXT = "modified category";

 

-        Category expectedSaveCategory = new Category();

-        expectedSaveCategory.setEntityId(VALID_ID);

+        Category expectedSaveCategory = new CategoryImpl();

+        expectedSaveCategory.setId(VALID_ID);

         expectedSaveCategory.setText(UPDATED_TEXT);

         expectedSaveCategory.setCreatedUser(validCreatedUser);

         expectedSaveCategory.setLastModifiedUser(validLastModifiedUser);

@@ -133,9 +135,9 @@
         expect(repository.get(VALID_ID)).andReturn(validCategory);

         expect(repository.save(expectedSaveCategory)).andReturn(expectedSaveCategory);

         replay(repository);

-        

+

         Category updatedCategory = service.update(VALID_ID, UPDATED_TEXT, validLastModifiedUser);

-        assertThat(updatedCategory.getEntityId(), is(VALID_ID));

+        assertThat(updatedCategory.getId(), is(VALID_ID));

         assertThat(updatedCategory.getText(), is(UPDATED_TEXT));

         assertThat(updatedCategory.getCreatedUser(), is(validCreatedUser));

         assertThat(updatedCategory.getLastModifiedUser(), is(validLastModifiedUser));

@@ -146,7 +148,7 @@
 

     @Test

     public void delete() {

-        expect(repository.get(validCategory.getEntityId())).andReturn(validCategory);

+        expect(repository.get(validCategory.getId())).andReturn(validCategory);

         repository.delete(validCategory);

         expectLastCall();

         replay(repository);

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultNewAccountServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultNewAccountServiceTest.java
index 8378fe6..86ccd06 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultNewAccountServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultNewAccountServiceTest.java
@@ -19,19 +19,11 @@
 
 package org.apache.rave.portal.service.impl;
 
-import static junit.framework.Assert.fail;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.rave.portal.model.Authority;
-import org.apache.rave.portal.model.PageLayout;
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.AuthorityImpl;
+import org.apache.rave.portal.model.impl.PageLayoutImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.service.AuthorityService;
 import org.apache.rave.portal.service.NewAccountService;
@@ -45,6 +37,12 @@
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.test.util.ReflectionTestUtils;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.fail;
+import static org.easymock.EasyMock.*;
+
 /**
  * Test class for {@link org.apache.rave.portal.service.impl.DefaultNewAccountService}
  */
@@ -61,7 +59,7 @@
     private final String VALID_PASSWORD = "valid.password";
     private final String VALID_LAYOUT_CODE = "valid.layout";
     private final String VALID_EMAIL = "valid.email";
-    private PageLayout validPageLayout;
+    private PageLayoutImpl validPageLayout;
     private SearchResult<Authority> validAuthoritySearchResult;
     private List<Authority> validAuthorityList;
 
@@ -77,14 +75,13 @@
 
         newAccountService = new DefaultNewAccountService(userService, pageLayoutService, authorityService);
 
-        validPageLayout = new PageLayout();
-        validPageLayout.setEntityId(99L);
+        validPageLayout = new PageLayoutImpl();
         validPageLayout.setNumberOfRegions(4L);
         validPageLayout.setCode(VALID_LAYOUT_CODE);
 
-        Authority role1 = new Authority();
+        Authority role1 = new AuthorityImpl();
         role1.setAuthority("DEFAULT_ROLE1");
-        Authority role2 = new Authority();
+        Authority role2 = new AuthorityImpl();
         role2.setAuthority("DEFAULT_ROLE2");
 
         validAuthorityList = new ArrayList<Authority>();
@@ -95,14 +92,14 @@
 
     @Test
     public void createNewAccountTest() throws Exception {
-        User newUser = new User();
+        UserImpl newUser = new UserImpl();
         newUser.setUsername(VALID_USER);
         newUser.setPassword(VALID_PASSWORD);
         newUser.setConfirmPassword(VALID_PASSWORD);
         newUser.setEmail(VALID_EMAIL);
         newUser.setDefaultPageLayoutCode(VALID_LAYOUT_CODE);
 
-        User expectedUser = new User();
+        User expectedUser = new UserImpl();
         expectedUser.setUsername(newUser.getUsername());
         expectedUser.setPassword(newUser.getPassword());
         expectedUser.setEmail(newUser.getEmail());
@@ -118,7 +115,7 @@
         expect(userService.getUserByEmail(VALID_EMAIL)).andReturn(null);
         expect(pageLayoutService.getPageLayoutByCode(VALID_LAYOUT_CODE)).andReturn(validPageLayout);
         expect(authorityService.getDefaultAuthorities()).andReturn(validAuthoritySearchResult);
-        userService.registerNewUser(expectedUser);
+        userService.registerNewUser(isA(User.class));
         expectLastCall();
         replay(userDetails, passwordEncoder, userService, pageLayoutService, authorityService);
 
@@ -129,14 +126,14 @@
 
     @Test
     public void createNewAccountTest_blankEmail() throws Exception {
-        User newUser = new User();
+        UserImpl newUser = new UserImpl();
         newUser.setUsername(VALID_USER);
         newUser.setPassword(VALID_PASSWORD);
         newUser.setConfirmPassword(VALID_PASSWORD);
         newUser.setEmail("");
         newUser.setDefaultPageLayoutCode(VALID_LAYOUT_CODE);
 
-        User expectedUser = new User();
+        User expectedUser = new UserImpl();
         expectedUser.setUsername(newUser.getUsername());
         expectedUser.setPassword(newUser.getPassword());
         expectedUser.setEmail(newUser.getEmail());
@@ -152,7 +149,7 @@
         //if the email is blank getUserByEmail should not be called so dont expect it
         expect(pageLayoutService.getPageLayoutByCode(VALID_LAYOUT_CODE)).andReturn(validPageLayout);
         expect(authorityService.getDefaultAuthorities()).andReturn(validAuthoritySearchResult);
-        userService.registerNewUser(expectedUser);
+        userService.registerNewUser(isA(User.class));
         expectLastCall();
         replay(userDetails, passwordEncoder, userService, pageLayoutService, authorityService);
 
@@ -164,9 +161,9 @@
     @Test
     public void failedAccountCreationTest_duplicateUsername() throws Exception {
         String duplicateUserName = "duplicateUserName";
-        User newUser = new User();
+        UserImpl newUser = new UserImpl();
         newUser.setUsername(duplicateUserName);
-        User existingUser = new User();
+        User existingUser = new UserImpl();
         existingUser.setUsername(duplicateUserName);
 
         expect(userService.getUserByUsername(duplicateUserName)).andReturn(existingUser);
@@ -183,10 +180,10 @@
     @Test
     public void failedAccountCreationTest_duplicateEmail() throws Exception {
         String duplicateEmail = "duplicateEmail";
-        User newUser = new User();
+        UserImpl newUser = new UserImpl();
         newUser.setUsername("newUser");
         newUser.setEmail(duplicateEmail);
-        User existingUser = new User();
+        User existingUser = new UserImpl();
         existingUser.setEmail(duplicateEmail);
 
         expect(userService.getUserByUsername("newUser")).andReturn(null);
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageLayoutServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageLayoutServiceTest.java
index 586c7fc..05e096c 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageLayoutServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageLayoutServiceTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.service.impl;

 

 import org.apache.rave.portal.model.PageLayout;

+import org.apache.rave.portal.model.impl.PageLayoutImpl;

 import org.apache.rave.portal.repository.PageLayoutRepository;

 import org.apache.rave.portal.service.PageLayoutService;

 import org.junit.Before;

@@ -29,9 +30,7 @@
 import java.util.List;

 

 import static org.easymock.EasyMock.*;

-import static org.hamcrest.CoreMatchers.is;

-import static org.hamcrest.CoreMatchers.nullValue;

-import static org.hamcrest.CoreMatchers.sameInstance;

+import static org.hamcrest.CoreMatchers.*;

 import static org.junit.Assert.assertThat;

 

 public class DefaultPageLayoutServiceTest {

@@ -47,7 +46,7 @@
         pageLayoutRepository = createMock(PageLayoutRepository.class);      

         pageLayoutService = new DefaultPageLayoutService(pageLayoutRepository);

         

-        validPageLayout = new PageLayout();

+        validPageLayout = new PageLayoutImpl();

         validPageLayout.setCode(VALID_LAYOUT_CODE);

     }

 

@@ -87,7 +86,7 @@
     public void getPageLayoutByCode_invalidPageLayout() {

         expect(pageLayoutRepository.getByPageLayoutCode(INVALID_LAYOUT_CODE)).andReturn(null);

         replay(pageLayoutRepository);

-        assertThat(pageLayoutService.getPageLayoutByCode(INVALID_LAYOUT_CODE), is(nullValue(PageLayout.class)));

+        assertThat(pageLayoutService.getPageLayoutByCode(INVALID_LAYOUT_CODE), is(nullValue()));

         verify(pageLayoutRepository);

     }    

 }
\ No newline at end of file
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
index c0f7b92..590802c 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPageServiceTest.java
@@ -20,9 +20,12 @@
 package org.apache.rave.portal.service.impl;

 

 import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.*;

 import org.apache.rave.portal.repository.*;

 import org.apache.rave.portal.service.PageService;

 import org.apache.rave.portal.service.UserService;

+import org.easymock.EasyMock;

+import org.easymock.IAnswer;

 import org.hamcrest.CoreMatchers;

 import org.junit.Before;

 import org.junit.Test;

@@ -58,21 +61,21 @@
     private final Long INVALID_REGION_WIDGET_ID = 100L;

     private final Long USER_PAGE_TYPE_ID = 1L;

     private final Long VALID_USER_ID = 9876L;

-            

+

     private Region targetRegion, originalRegion, lockedRegion;

     private Widget validWidget;

     private RegionWidget validRegionWidget;

-    private User user;

+    private UserImpl user;

     private PageLayout pageLayout;

     private String defaultPageName = "Main";

     private Page page, page2;

     private PageUser pageUser, pageUser2;

     private List<Page> pageList;

     private List<PageUser> pageUserList;

-    

 

     @Before

     public void setup() {

+

         pageRepository = createMock(PageRepository.class);

         pageTemplateRepository = createMock(PageTemplateRepository.class);

         regionRepository = createMock(RegionRepository.class);

@@ -80,53 +83,52 @@
         regionWidgetRepository = createMock(RegionWidgetRepository.class);

         pageLayoutRepository = createMock(PageLayoutRepository.class);

         userService = createMock(UserService.class);

-       

+

         pageService = new DefaultPageService(pageRepository, pageTemplateRepository, regionRepository, widgetRepository, regionWidgetRepository,

                                              pageLayoutRepository, userService, defaultPageName);

-        

-        validWidget = new Widget(1L, "http://dummy.apache.org/widgets/widget.xml");

 

-        page = new Page(PAGE_ID, user);

-        pageUser = new PageUser(user, page, 1L);

+        validWidget = new WidgetImpl(1L, "http://dummy.apache.org/widgets/widget.xml");

+

+        page = new PageImpl(PAGE_ID, user);

+        pageUser = new PageUserImpl(user, page, 1L);

         page.setMembers(new ArrayList<PageUser>());

         page.getMembers().add(pageUser);

-        

-        page2 = new Page(99L, user);

-        pageUser2 = new PageUser(user, page2, 2L);

+

+        page2 = new PageImpl(99L, user);

+        pageUser2 = new PageUserImpl(user, page2, 2L);

         page2.setMembers(new ArrayList<PageUser>());

         page2.getMembers().add(pageUser2);

 

-        targetRegion = new Region();

-        targetRegion.setEntityId(2L);

+        targetRegion = new RegionImpl();

+        targetRegion.setId(2L);

         targetRegion.setLocked(false);

         targetRegion.setRegionWidgets(new ArrayList<RegionWidget>());

-        targetRegion.getRegionWidgets().add(new RegionWidget(1L, validWidget, targetRegion, 0));

-        targetRegion.getRegionWidgets().add(new RegionWidget(2L, validWidget, targetRegion, 1));

-        targetRegion.getRegionWidgets().add(new RegionWidget(3L, validWidget, targetRegion, 2));

+        targetRegion.getRegionWidgets().add(new RegionWidgetImpl(1L, validWidget, targetRegion, 0));

+        targetRegion.getRegionWidgets().add(new RegionWidgetImpl(2L, validWidget, targetRegion, 1));

+        targetRegion.getRegionWidgets().add(new RegionWidgetImpl(3L, validWidget, targetRegion, 2));

         targetRegion.setPage(page);

 

-        originalRegion = new Region();

-        originalRegion.setEntityId(1L);

+        originalRegion = new RegionImpl();

+        originalRegion.setId(1L);

         originalRegion.setLocked(false);

         originalRegion.setRegionWidgets(new ArrayList<RegionWidget>());

-        originalRegion.getRegionWidgets().add(new RegionWidget(4L, validWidget, targetRegion, 0));

-        originalRegion.getRegionWidgets().add(new RegionWidget(5L, validWidget, targetRegion, 1));

-        originalRegion.getRegionWidgets().add(new RegionWidget(6L, validWidget, targetRegion, 2));

-        

-        lockedRegion = new Region();

+        originalRegion.getRegionWidgets().add(new RegionWidgetImpl(4L, validWidget, targetRegion, 0));

+        originalRegion.getRegionWidgets().add(new RegionWidgetImpl(5L, validWidget, targetRegion, 1));

+        originalRegion.getRegionWidgets().add(new RegionWidgetImpl(6L, validWidget, targetRegion, 2));

+

+        lockedRegion = new RegionImpl();

         lockedRegion.setLocked(true);

         lockedRegion.setPage(page);

-        

-        pageLayout = new PageLayout();

-        pageLayout.setEntityId(1L);

+

+        pageLayout = new PageLayoutImpl();

         pageLayout.setCode(PAGE_LAYOUT_CODE);

         pageLayout.setNumberOfRegions(3L);

-        

-        user = new User();

-        user.setEntityId(1L);

-        user.setUsername("acarlucci"); 

+

+        user = new UserImpl();

+        user.setUsername("acarlucci");

+        user.setId(1L);

         user.setDefaultPageLayout(pageLayout);

-        

+

         pageList = new ArrayList<Page>();

         pageList.add(page2);

         pageList.add(page);

@@ -135,8 +137,8 @@
         pageUserList.add(pageUser);

         pageUserList.add(pageUser2);

 

-        validRegionWidget = new RegionWidget();

-        validRegionWidget.setEntityId(VALID_REGION_WIDGET_ID);

+        validRegionWidget = new RegionWidgetImpl();

+        validRegionWidget.setId(VALID_REGION_WIDGET_ID);

         validRegionWidget.setWidget(validWidget);

         validRegionWidget.setRegion(originalRegion);

     }

@@ -149,7 +151,7 @@
         replay(pageRepository);

 

         assertThat(pageService.getAllUserPages(VALID_USER_ID), CoreMatchers.sameInstance(VALID_PAGES));

-        

+

         verify(pageRepository);

     }

 

@@ -157,7 +159,7 @@
     @Test

     public void getAllPersonProfilePages_userHasPersonPage() {

         List<Page> VALID_PAGES = new ArrayList<Page>();

-        Page personPage = new Page();

+        Page personPage = new PageImpl();

         VALID_PAGES.add(personPage);

 

         expect(pageRepository.getAllPages(VALID_USER_ID, PageType.PERSON_PROFILE)).andReturn(VALID_PAGES);

@@ -171,9 +173,9 @@
     @Test

     public void getAllPersonProfilePages_noPersonPage() {

         List<Page> VALID_PAGES = new ArrayList<Page>();

-        Page personPage = new Page();

-        PageTemplate pageTemplate = new PageTemplate();

-        User user = new User();

+        Page personPage = new PageImpl();

+        PageTemplate pageTemplate = new PageTemplateImpl();

+        UserImpl user = new UserImpl();

 

         expect(pageRepository.getAllPages(VALID_USER_ID, PageType.PERSON_PROFILE)).andReturn(VALID_PAGES);

         expect(userService.getUserById(isA(Long.class))).andReturn(user).once();

@@ -190,14 +192,14 @@
     public void addNewUserPage_noExistingPages() {

         final String PAGE_NAME = "my new page";

         final Long EXPECTED_RENDER_SEQUENCE = 1L;

-        PageTemplate pageTemplate = new PageTemplate() ;

-        Page expectedPage = new Page();

-        expectedPage.setName(PAGE_NAME);       

+        PageTemplate pageTemplate = new PageTemplateImpl() ;

+        Page expectedPage = new PageImpl();

+        expectedPage.setName(PAGE_NAME);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

-        expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));    

+        expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

         expectedPage.setPageType(PageType.USER);

-        PageUser lPageUser = new PageUser(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

+        PageUser lPageUser = new PageUserImpl(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

         List<PageUser> members = new ArrayList<PageUser>();

         members.add(lPageUser);

         expectedPage.setMembers(members);

@@ -206,7 +208,7 @@
         expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

         expect(pageTemplateRepository.getDefaultPage(PageType.USER)).andReturn(pageTemplate);

         expect(pageRepository.createPageForUser(user, pageTemplate)).andReturn(expectedPage);

-        expect(pageRepository.getAllPages(user.getEntityId(), PageType.USER)).andReturn(new ArrayList<Page>());

+        expect(pageRepository.getAllPages(user.getId(), PageType.USER)).andReturn(new ArrayList<Page>());

 

         replay(userService, pageLayoutRepository, pageRepository, pageTemplateRepository);

 

@@ -224,7 +226,7 @@
         final String PAGE_NAME = "my new page";

         final Long EXPECTED_RENDER_SEQUENCE = 1L;

 

-        Page expectedPage = new Page();

+        Page expectedPage = new PageImpl();

         expectedPage.setName(PAGE_NAME);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

@@ -233,10 +235,15 @@
 

         expect(userService.getAuthenticatedUser()).andReturn(user);

         expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

-        expect(pageRepository.save(expectedPage)).andReturn(expectedPage);

+        expect(pageRepository.save(expectedPage)).andAnswer(new IAnswer<Page>() {

+            @Override

+            public Page answer() throws Throwable {

+                return (Page)EasyMock.getCurrentArguments()[0];

+            }

+        });

         expect(pageTemplateRepository.getDefaultPage(PageType.USER)).andThrow(new NoResultException("No Result Exception"));

 

-        expect(pageRepository.getAllPages(user.getEntityId(), PageType.USER)).andReturn(new ArrayList<Page>());

+        expect(pageRepository.getAllPages(user.getId(), PageType.USER)).andReturn(new ArrayList<Page>());

         replay(userService, pageLayoutRepository, pageRepository, pageTemplateRepository);

 

         Page newPage = pageService.addNewUserPage(PAGE_NAME, PAGE_LAYOUT_CODE);

@@ -253,7 +260,7 @@
         final String PAGE_NAME = "my new page";

         final Long EXPECTED_RENDER_SEQUENCE = 1L;

 

-        Page expectedPage = new Page();

+        Page expectedPage = new PageImpl();

         expectedPage.setName(PAGE_NAME);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

@@ -262,10 +269,15 @@
 

         expect(userService.getAuthenticatedUser()).andReturn(user);

         expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

-        expect(pageRepository.save(expectedPage)).andReturn(expectedPage);

+        expect(pageRepository.save(expectedPage)).andAnswer(new IAnswer<Page>() {

+            @Override

+            public Page answer() throws Throwable {

+                return (Page)EasyMock.getCurrentArguments()[0];

+            }

+        });

         expect(pageTemplateRepository.getDefaultPage(PageType.USER)).andThrow(new NonUniqueResultException("Non-Unique Result Exception"));

 

-        expect(pageRepository.getAllPages(user.getEntityId(), PageType.USER)).andReturn(new ArrayList<Page>());

+        expect(pageRepository.getAllPages(user.getId(), PageType.USER)).andReturn(new ArrayList<Page>());

         replay(userService, pageLayoutRepository, pageRepository, pageTemplateRepository);

 

         Page newPage = pageService.addNewUserPage(PAGE_NAME, PAGE_LAYOUT_CODE);

@@ -281,25 +293,25 @@
     public void addNewUserPage_noExistingPages_and_have_template() {

         final String PAGE_NAME = "my new page";

         final Long EXPECTED_RENDER_SEQUENCE = 1L;

-        PageTemplate pageTemplate = new PageTemplate();

-        Page userPage = new Page();

+        PageTemplate pageTemplate = new PageTemplateImpl();

+        Page userPage = new PageImpl();

         userPage.setName("Page Template");

         userPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

 

-        Page expectedPage = new Page();

+        Page expectedPage = new PageImpl();

         expectedPage.setName(PAGE_NAME);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

         expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

         expectedPage.setPageType(PageType.USER);

-        PageUser lPageUser = new PageUser(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

+        PageUser lPageUser = new PageUserImpl(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

         List<PageUser> members = new ArrayList<PageUser>();

         members.add(lPageUser);

         userPage.setMembers(members);

 

         expect(userService.getAuthenticatedUser()).andReturn(user);

         expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

-        expect(pageRepository.getAllPages(user.getEntityId(), PageType.USER)).andReturn(new ArrayList<Page>());

+        expect(pageRepository.getAllPages(user.getId(), PageType.USER)).andReturn(new ArrayList<Page>());

         expect(pageRepository.createPageForUser(user, pageTemplate)).andReturn(userPage);

         expect(pageTemplateRepository.getDefaultPage(PageType.USER)).andReturn(pageTemplate);

         replay(userService, pageLayoutRepository, pageRepository, pageTemplateRepository);

@@ -319,22 +331,27 @@
         final String PAGE_NAME = "my new page";

         final Long EXPECTED_RENDER_SEQUENCE = 2L;

         List<Page> existingPages = new ArrayList<Page>();

-        existingPages.add(new Page());

-                      

-        Page expectedPage = new Page();

+        existingPages.add(new PageImpl());

+

+        Page expectedPage = new PageImpl();

         expectedPage.setName(PAGE_NAME);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

         expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

-        PageUser lPageUser = new PageUser(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

+        PageUser lPageUser = new PageUserImpl(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

         List<PageUser> members = new ArrayList<PageUser>();

         members.add(lPageUser);

         expectedPage.setMembers(members);

-                

+

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);       

-        expect(pageRepository.save(expectedPage)).andReturn(expectedPage);

-        expect(pageRepository.getAllPages(user.getEntityId(), PageType.USER)).andReturn(existingPages);

+        expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

+        expect(pageRepository.save(expectedPage)).andAnswer(new IAnswer<Page>() {

+            @Override

+            public Page answer() throws Throwable {

+                return (Page)EasyMock.getCurrentArguments()[0];

+            }

+        });

+        expect(pageRepository.getAllPages(user.getId(), PageType.USER)).andReturn(existingPages);

         replay(userService, pageLayoutRepository, pageRepository);

 

         Page newPage = pageService.addNewUserPage(PAGE_NAME, PAGE_LAYOUT_CODE);

@@ -357,13 +374,13 @@
         final Long EXPECTED_RENDER_SEQUENCE = 1L;

         final Long EXPECTED_PARENT_RENDER_SEQUENCE = 1L;

 

-        Page expectedPage = new Page();

+        Page expectedPage = new PageImpl();

         expectedPage.setName(PAGE_NAME);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

         expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

 

-        Page parentPage = new Page();

+        Page parentPage = new PageImpl();

         parentPage.setName(PARENT_PAGE_NAME);

         parentPage.setOwner(user);

         parentPage.setPageLayout(pageLayout);

@@ -371,7 +388,7 @@
         parentPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

 

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);       

+        expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

         expect(pageRepository.save(expectedPage)).andReturn(expectedPage);

         replay(userService, pageLayoutRepository,  pageRepository);

 

@@ -392,15 +409,15 @@
         final String PARENT_PAGE_NAME = "my parent page";

         final Long EXPECTED_RENDER_SEQUENCE = 2L;

         List<Page> existingPages = new ArrayList<Page>();

-        existingPages.add(new Page());

+        existingPages.add(new PageImpl());

 

-        Page expectedPage = new Page();

+        Page expectedPage = new PageImpl();

         expectedPage.setName(PAGE_NAME);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

         expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

 

-        Page parentPage = new Page();

+        Page parentPage = new PageImpl();

         parentPage.setName(PARENT_PAGE_NAME);

         parentPage.setOwner(user);

         parentPage.setPageLayout(pageLayout);

@@ -408,7 +425,7 @@
         parentPage.setSubPages(existingPages);

 

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);        

+        expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

         expect(pageRepository.save(expectedPage)).andReturn(expectedPage);

         replay(userService, pageLayoutRepository,  pageRepository);

 

@@ -422,50 +439,50 @@
 

         verify(userService, pageLayoutRepository,  pageRepository);

     }

-   

+

     @Test

     public void addNewDefaultUserPage() {

-        

+

         final Long EXPECTED_RENDER_SEQUENCE = 1L;

-        PageTemplate pageTemplate = new PageTemplate();

-        Page expectedPage = new Page();

+        PageTemplate pageTemplate = new PageTemplateImpl();

+        Page expectedPage = new PageImpl();

         expectedPage.setName(defaultPageName);

         expectedPage.setOwner(user);

         expectedPage.setPageLayout(pageLayout);

         expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));

-        PageUser lPageUser = new PageUser(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

+        PageUser lPageUser = new PageUserImpl(user, expectedPage, EXPECTED_RENDER_SEQUENCE);

         List<PageUser> members = new ArrayList<PageUser>();

         members.add(lPageUser);

         expectedPage.setMembers(members);

-                

-        expect(userService.getUserById(user.getEntityId())).andReturn(user);

+

+        expect(userService.getUserById(user.getId())).andReturn(user);

         expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);

         expect(pageTemplateRepository.getDefaultPage(PageType.USER)).andReturn(pageTemplate);

         expect(pageRepository.createPageForUser(user, pageTemplate)).andReturn(expectedPage);

-        expect(pageRepository.getAllPages(user.getEntityId(), PageType.USER)).andReturn(new ArrayList<Page>());

+        expect(pageRepository.getAllPages(user.getId(), PageType.USER)).andReturn(new ArrayList<Page>());

         replay(userService, pageLayoutRepository, pageRepository, pageTemplateRepository);

 

-        Page newPage = pageService.addNewDefaultUserPage(user.getEntityId());

+        Page newPage = pageService.addNewDefaultUserPage(user.getId());

         assertThat(newPage.getMembers().get(0).getRenderSequence(), is(EXPECTED_RENDER_SEQUENCE));

         assertThat(newPage.getName(), is(defaultPageName));

         assertThat(newPage.getRegions().size(), is(pageLayout.getNumberOfRegions().intValue()));

-        

+

         verify(userService, pageLayoutRepository, pageRepository, pageTemplateRepository);

     }

-    

+

     @Test

     public void getDefaultPageName() {

         assertThat(pageService.getDefaultPageName(), is(defaultPageName));

     }

-  

+

     @Test

     public void deletePage() {

         List<PageUser> pageUserListAfterDelete = new ArrayList<PageUser>(pageUserList);

         pageUserListAfterDelete.remove(pageUser);

-        

+

         expect(userService.getAuthenticatedUser()).andReturn(user);

         expect(pageRepository.get(PAGE_ID)).andReturn(page);

-        expect(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER)).andReturn(pageUserListAfterDelete);

+        expect(pageRepository.getPagesForUser(user.getId(), PageType.USER)).andReturn(pageUserListAfterDelete);

         expect(pageRepository.save(page2)).andReturn(page2);

 

         pageRepository.delete(page);

@@ -476,7 +493,7 @@
         verify(userService);

         verify(pageRepository);

     }

-    

+

     @Test

     public void deletePage_invalidId() {

         final long INVALID_PAGE_ID = -999L;

@@ -486,7 +503,7 @@
         expect(pageRepository.get(INVALID_PAGE_ID)).andReturn(page);

         pageRepository.delete(page);

         expectLastCall();

-        expect(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER)).andReturn(pageUserListAfterDelete);

+        expect(pageRepository.getPagesForUser(user.getId(), PageType.USER)).andReturn(pageUserListAfterDelete);

         expect(pageRepository.save(page2)).andReturn(page2);

         expect(pageRepository.save(page)).andReturn(page);

         replay(userService);

@@ -500,7 +517,7 @@
     @Test

     public void deletePages() {

         final int EXPECTED_DELETED_PAGE_COUNT = 7;

-        expect(pageRepository.deletePages(VALID_USER_ID, PageType.USER)).andReturn(EXPECTED_DELETED_PAGE_COUNT);     

+        expect(pageRepository.deletePages(VALID_USER_ID, PageType.USER)).andReturn(EXPECTED_DELETED_PAGE_COUNT);

         replay(pageRepository);

         assertThat(pageService.deletePages(VALID_USER_ID, PageType.USER), is(EXPECTED_DELETED_PAGE_COUNT));

         verify(pageRepository);

@@ -513,7 +530,7 @@
 

         expect(regionWidgetRepository.get(REGION_WIDGET_ID)).andReturn(validRegionWidget);

         replay(regionWidgetRepository);

-        

+

         RegionWidget widget = pageService.moveRegionWidget(REGION_WIDGET_ID, newPosition, TO_REGION_ID, FROM_REGION_ID);

 

         verify(regionRepository, regionWidgetRepository);

@@ -648,12 +665,12 @@
     }

 

     @Test(expected = IllegalArgumentException.class)

-    public void moveRegionWidget_invalidTarget() {       

+    public void moveRegionWidget_invalidTarget() {

         pageService.moveRegionWidget(-1L, 0, 5L, 6L);

     }

 

     @Test(expected = IllegalArgumentException.class)

-    public void moveRegionWidget_invalidTarget_sameRegion() {       

+    public void moveRegionWidget_invalidTarget_sameRegion() {

         pageService.moveRegionWidget(-1L, 0, 5L, 5L);

     }

 

@@ -661,11 +678,11 @@
     public void addWigetToPage_valid() {

         final long WIDGET_ID = 1L;

 

-        Page value = new Page();

+        Page value = new PageImpl();

         value.setRegions(new ArrayList<Region>());

         value.getRegions().add(originalRegion);

         value.getRegions().add(targetRegion);

-        Widget widget = new Widget();

+        Widget widget = new WidgetImpl();

 

         expect(pageRepository.get(PAGE_ID)).andReturn(value);

         expect(widgetRepository.get(WIDGET_ID)).andReturn(widget);

@@ -682,7 +699,7 @@
 

         verifyPositions(0, instance, true);

         assertThat(originalRegion.getRegionWidgets().get(0), is(sameInstance(instance)));

-        assertThat(instance.getWidget(), is(sameInstance(widget)));

+        assertThat(instance.getWidget().getId(), is(equalTo(widget.getId())));

 

     }

 

@@ -691,11 +708,11 @@
         originalRegion.setLocked(true);

         final long WIDGET_ID = 1L;

 

-        Page value = new Page();

+        Page value = new PageImpl();

         value.setRegions(new ArrayList<Region>());

         value.getRegions().add(originalRegion);

         value.getRegions().add(targetRegion);

-        Widget widget = new Widget();

+        Widget widget = new WidgetImpl();

 

         expect(pageRepository.get(PAGE_ID)).andReturn(value);

         expect(widgetRepository.get(WIDGET_ID)).andReturn(widget);

@@ -721,35 +738,30 @@
         originalRegion = null;

         final long WIDGET_ID = 1L;

 

-        Page value = new Page();

+        Page value = new PageImpl();

         value.setRegions(new ArrayList<Region>());

         value.getRegions().add(originalRegion);

         value.getRegions().add(targetRegion);

-        Widget widget = new Widget();

+        Widget widget = new WidgetImpl();

 

         expect(pageRepository.get(PAGE_ID)).andReturn(value);

         expect(widgetRepository.get(WIDGET_ID)).andReturn(widget);

         expect(regionRepository.save(originalRegion)).andReturn(originalRegion);

-        replay(pageRepository);

-        replay(regionRepository);

-        replay(widgetRepository);

+        replay(pageRepository,regionRepository,widgetRepository);

 

         RegionWidget instance = pageService.addWidgetToPage(PAGE_ID, WIDGET_ID);

 

-        verify(pageRepository);

-        verify(regionRepository);

-        verify(widgetRepository);

+        verify(pageRepository,regionRepository,widgetRepository);

 

         verifyPositions(0, instance, true);

         assertThat(originalRegion.getRegionWidgets().get(0), is(sameInstance(instance)));

-        assertThat(instance.getWidget(), is(sameInstance(widget)));

-

-    }    

+        assertThat(instance.getWidget(), is(sameInstance(widget)))         ;

+    }

 

     @Test(expected = IllegalArgumentException.class)

     public void addWidgetToPage_invalidWidget() {

         long WIDGET_ID = -1L;

-        expect(pageRepository.get(PAGE_ID)).andReturn(new Page());

+        expect(pageRepository.get(PAGE_ID)).andReturn(new PageImpl());

         expect(widgetRepository.get(WIDGET_ID)).andReturn(null);

         replay(pageRepository);

         replay(regionRepository);

@@ -762,7 +774,7 @@
     public void addWidgetToPage_invalidPage() {

         long WIDGET_ID = -1L;

         expect(pageRepository.get(PAGE_ID)).andReturn(null);

-        expect(widgetRepository.get(WIDGET_ID)).andReturn(new Widget());

+        expect(widgetRepository.get(WIDGET_ID)).andReturn(new WidgetImpl());

         replay(pageRepository);

         replay(regionRepository);

         replay(widgetRepository);

@@ -774,9 +786,9 @@
     public void removeWidgetFromPage_validWidget() {

         long WIDGET_ID = 1L;

         long REGION_ID = 2L;

-        RegionWidget regionWidget = new RegionWidget(WIDGET_ID);

-        regionWidget.setRegion(new Region(REGION_ID));

-        Region region = new Region();

+        RegionWidget regionWidget = new RegionWidgetImpl(WIDGET_ID);

+        regionWidget.setRegion(new RegionImpl(REGION_ID));

+        Region region = new RegionImpl();

 

         expect(regionWidgetRepository.get(WIDGET_ID)).andReturn(regionWidget);

         regionWidgetRepository.delete(regionWidget);

@@ -795,9 +807,9 @@
     public void removeWidgetFromPage_lockedRegion() {

         long WIDGET_ID = 1L;

         long REGION_ID = 2L;

-        Region region = new Region(REGION_ID);

+        Region region = new RegionImpl(REGION_ID);

         region.setLocked(true);

-        RegionWidget regionWidget = new RegionWidget(WIDGET_ID);

+        RegionWidget regionWidget = new RegionWidgetImpl(WIDGET_ID);

         regionWidget.setRegion(region);

 

         expect(regionWidgetRepository.get(WIDGET_ID)).andReturn(regionWidget);

@@ -814,9 +826,9 @@
     public void removeWidgetFromPage_lockedRegionWidget() {

         long WIDGET_ID = 1L;

         long REGION_ID = 2L;

-        Region region = new Region(REGION_ID);

+        Region region = new RegionImpl(REGION_ID);

         region.setLocked(true);

-        RegionWidget regionWidget = new RegionWidget(WIDGET_ID);

+        RegionWidget regionWidget = new RegionWidgetImpl(WIDGET_ID);

         regionWidget.setLocked(true);

         regionWidget.setRegion(region);

 

@@ -839,7 +851,7 @@
 

         pageService.removeWidgetFromPage(WIDGET_ID);

     }

-    

+

     @Test

     public void getPage() {

         expect(pageRepository.get(PAGE_ID)).andReturn(page);

@@ -859,35 +871,35 @@
     public void getPageFromList_invalidId() {

         assertThat(pageService.getPageFromList(INVALID_PAGE_ID, pageList), is(nullValue(Page.class)));

     }

-    

+

     @Test

     public void getDefaultPageFromList_validList() {

         assertThat(pageService.getDefaultPageFromList(pageList), is(page2));

-    }   

-    

+    }

+

     @Test

     public void getDefaultPageFromList_emptyList() {

         assertThat(pageService.getDefaultPageFromList(new ArrayList<Page>()), is(nullValue(Page.class)));

-    }   

-    

+    }

+

     @Test

     public void getDefaultPageFromList_nullList() {

         assertThat(pageService.getDefaultPageFromList(null), is(nullValue(Page.class)));

-    }      

-    

+    }

+

     @Test

     public void movePage() {

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        expect(pageRepository.getSingleRecord(user.getEntityId(), PAGE_ID)).andReturn(pageUser);

-        expect(pageRepository.getSingleRecord(user.getEntityId(), page2.getEntityId())).andReturn(pageUser2);

-        expect(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER)).andReturn(pageUserList);

+        expect(pageRepository.getSingleRecord(user.getId(), PAGE_ID)).andReturn(pageUser);

+        expect(pageRepository.getSingleRecord(user.getId(), page2.getId())).andReturn(pageUser2);

+        expect(pageRepository.getPagesForUser(user.getId(), PageType.USER)).andReturn(pageUserList);

 

         expect(pageRepository.save(page)).andReturn(page);

         expect(pageRepository.save(page2)).andReturn(page);

         replay(userService);

         replay(pageRepository);

 

-        Page p = pageService.movePage(PAGE_ID, page2.getEntityId());

+        Page p = pageService.movePage(PAGE_ID, page2.getId());

 

         assertThat(pageUser.getRenderSequence(), is(2L));

         assertThat(pageUser2.getRenderSequence(), is(1L));

@@ -897,19 +909,19 @@
     }

 

     @Test(expected=RuntimeException.class)

-    public void movePage_invalidPageId() {               

+    public void movePage_invalidPageId() {

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        expect(pageRepository.getSingleRecord(user.getEntityId(), INVALID_PAGE_ID)).andReturn(null);

-        expect(pageRepository.getSingleRecord(user.getEntityId(), page2.getEntityId())).andReturn(pageUser2);

-        expect(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER)).andReturn(pageUserList);

+        expect(pageRepository.getSingleRecord(user.getId(), INVALID_PAGE_ID)).andReturn(null);

+        expect(pageRepository.getSingleRecord(user.getId(), page2.getId())).andReturn(pageUser2);

+        expect(pageRepository.getPagesForUser(user.getId(), PageType.USER)).andReturn(pageUserList);

 

         expect(pageRepository.get(INVALID_PAGE_ID)).andReturn(null);

-        expect(pageRepository.get(page2.getEntityId())).andReturn(page2);

-        expect(pageRepository.getAllPages(user.getEntityId(), PageType.USER)).andReturn(pageList);

+        expect(pageRepository.get(page2.getId())).andReturn(page2);

+        expect(pageRepository.getAllPages(user.getId(), PageType.USER)).andReturn(pageList);

         replay(userService);

         replay(pageRepository);

 

-        pageService.movePage(INVALID_PAGE_ID, page2.getEntityId());

+        pageService.movePage(INVALID_PAGE_ID, page2.getId());

 

         verify(userService);

         verify(pageRepository);

@@ -918,14 +930,14 @@
     @Test

     public void movePageToDefault() {

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        expect(pageRepository.getSingleRecord(user.getEntityId(), page2.getEntityId())).andReturn(pageUser2);

-        expect(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER)).andReturn(pageUserList);

+        expect(pageRepository.getSingleRecord(user.getId(), page2.getId())).andReturn(pageUser2);

+        expect(pageRepository.getPagesForUser(user.getId(), PageType.USER)).andReturn(pageUserList);

         expect(pageRepository.save(page)).andReturn(page);

         expect(pageRepository.save(page2)).andReturn(page);

         replay(userService);

         replay(pageRepository);

 

-        pageService.movePageToDefault(page2.getEntityId());

+        pageService.movePageToDefault(page2.getId());

         assertThat(pageUser2.getRenderSequence(), is(1L));

         assertThat(pageUser.getRenderSequence(), is(2L));

 

@@ -934,10 +946,10 @@
     }

 

     @Test(expected=RuntimeException.class)

-    public void movePageToDefault_invalidPageId() {               

+    public void movePageToDefault_invalidPageId() {

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        expect(pageRepository.getSingleRecord(user.getEntityId(), INVALID_PAGE_ID)).andReturn(null);

-        expect(pageRepository.getPagesForUser(user.getEntityId(), PageType.USER)).andReturn(pageUserList);

+        expect(pageRepository.getSingleRecord(user.getId(), INVALID_PAGE_ID)).andReturn(null);

+        expect(pageRepository.getPagesForUser(user.getId(), PageType.USER)).andReturn(pageUserList);

         replay(userService);

         replay(pageRepository);

 

@@ -952,13 +964,13 @@
         String newName = "new page name";

         String layoutName = "layout name";

 

-        PageLayout layout = createStrictMock(PageLayout.class);

+        PageLayoutImpl layout = createStrictMock(PageLayoutImpl.class);

         expect(layout.getNumberOfRegions()).andReturn(new Long(2)).anyTimes();

         replay(layout);

 

         //create a strict mock that ensures that the appropriate setters are

         //called, rather than checking the return value from the function

-        Page curPage = createStrictMock(Page.class);

+        Page curPage = createStrictMock(PageImpl.class);

         expect(curPage.getPageLayout()).andReturn(layout);

         curPage.setName(newName);

         curPage.setPageLayout(layout);

@@ -980,30 +992,42 @@
     public void updatePage_addRegion() {

         String newName = "new page name";

         String layoutName = "layout name";

+        String layoutCode = "CODE";

 

         List<Region> regions = new ArrayList<Region>();

-        Region region = createStrictMock(Region.class);

-        expect(region.getRenderOrder()).andReturn(1);

-        replay(region);

-        regions.add(new Region());

+        Region region = new RegionImpl();

+        region.setId(99L);

+        region.setRenderOrder(1);

+        regions.add(new RegionImpl());

         regions.add(region);

 

-        PageLayout prevLayout = createStrictMock(PageLayout.class);

-        expect(prevLayout.getNumberOfRegions()).andReturn(new Long(2)).anyTimes();

-        replay(prevLayout);

-        

-        PageLayout layout = createStrictMock(PageLayout.class);

-        expect(layout.getNumberOfRegions()).andReturn(new Long(3)).anyTimes();

-        //expect(layout.equals(layout)).andReturn((boolean) true);

-        replay(layout);

+        PageLayout prevLayout = new PageLayoutImpl();

+        prevLayout.setNumberOfRegions(2L);

+        prevLayout.setCode("NEW");

+

+        PageLayoutImpl layout = new PageLayoutImpl();

+        layout.setNumberOfRegions(3L);

+        layout.setCode(layoutCode);

+

 

         //create a strict mock that ensures that the appropriate setters are

         //called, rather than checking the return value from the function

         Page curPage = createStrictMock(Page.class);

         expect(curPage.getPageLayout()).andReturn(prevLayout);

         expect(curPage.getRegions()).andReturn(regions);

+        expect(curPage.getId()).andReturn(PAGE_ID).anyTimes();

+        /*expect(curPage.getMembers()).andReturn(new ArrayList<PageUser>());

+        expect(curPage.getName()).andReturn(newName);

+        expect(curPage.getOwner()).andReturn(user);

+        expect(curPage.getPageLayout()).andReturn(layout);

+        expect(curPage.getPageType()).andReturn(PageType.USER);

+        expect(curPage.getParentPage()).andReturn(null);

+        expect(curPage.getRegions()).andReturn(regions);

+        expect(curPage.getSubPages()).andReturn(new ArrayList<Page>()); */

         curPage.setName(newName);

+        expectLastCall();

         curPage.setPageLayout(layout);

+        expectLastCall();

         replay(curPage);

 

         expect(pageRepository.get(PAGE_ID)).andReturn(curPage);

@@ -1015,146 +1039,145 @@
 

         pageService.updatePage(PAGE_ID, newName, layoutName);

         assertThat(regions.size(), is(3));

-        assertThat(regions.get(regions.size()-1).getPage(), is(curPage));

-

+        //assertThat(regions.get(regions.size()-1).getPage().getId(), is(PAGE_ID));

         verify(curPage);

     }

-    

-    

+

+

     @Test

     public void updatePage_removeRegion_noWidgets() {

         String newName = "new page name";

         String layoutName = "layout name";

-        

+

         List<Region> regions = new ArrayList<Region>();

         Region region = createStrictMock(Region.class);

         expect(region.getRegionWidgets()).andReturn(new ArrayList<RegionWidget>());

         expect(region.getRenderOrder()).andReturn(1);

         replay(region);

         regions.add(region);

-        

+

         Region deletedRegion = createStrictMock(Region.class);

         expect(deletedRegion.getRegionWidgets()).andReturn(new ArrayList<RegionWidget>());

         replay(deletedRegion);

         regions.add(deletedRegion);

-        

-        PageLayout prevLayout = createStrictMock(PageLayout.class);

+

+        PageLayout prevLayout = createStrictMock(PageLayoutImpl.class);

         expect(prevLayout.getNumberOfRegions()).andReturn(new Long(2)).anyTimes();

         replay(prevLayout);

-        

-        PageLayout layout = createStrictMock(PageLayout.class);

+

+        PageLayoutImpl layout = createStrictMock(PageLayoutImpl.class);

         expect(layout.getNumberOfRegions()).andReturn(new Long(1)).anyTimes();

         replay(layout);

-        

+

         regionRepository.delete(deletedRegion);

         expect(regionRepository.save(region)).andReturn(region);

         replay(regionRepository);

-        

+

         //create a strict mock that ensures that the appropriate setters are

         //called, rather than checking the return value from the function

-        Page curPage = createStrictMock(Page.class);

+        Page curPage = createStrictMock(PageImpl.class);

         expect(curPage.getPageLayout()).andReturn(prevLayout);

         expect(curPage.getRegions()).andReturn(regions);

         curPage.setName(newName);

         curPage.setPageLayout(layout);

         replay(curPage);

-        

+

         expect(pageRepository.get(PAGE_ID)).andReturn(curPage);

         expect(pageRepository.save(curPage)).andReturn(curPage);

         replay(pageRepository);

-        

+

         expect(pageLayoutRepository.getByPageLayoutCode(layoutName)).andReturn(layout);

         replay(pageLayoutRepository);

-        

+

         pageService.updatePage(PAGE_ID, newName, layoutName);

-        

+

         verify(curPage);

     }

-    

-    

+

+

     @Test

     public void updatePage_removeRegion_moveWidgetToEmptyColumn() {

         String newName = "new page name";

         String layoutName = "layout name";

-        

-        

+

+

         List<RegionWidget> newLastWidgetColumn = new ArrayList<RegionWidget>();

-        

+

         List<Region> regions = new ArrayList<Region>();

         Region region = createStrictMock(Region.class);

         expect(region.getRegionWidgets()).andReturn(newLastWidgetColumn).times(2);

         expect(region.getRenderOrder()).andReturn(1);

         replay(region);

         regions.add(region);

-        

-        

+

+

         RegionWidget widget = createStrictMock(RegionWidget.class);

         widget.setRegion(region);

         widget.setRenderOrder(1);

         replay(widget);

         List<RegionWidget> movedWidgets = new ArrayList<RegionWidget>();

         movedWidgets.add(widget);

-        

+

         Region deletedRegion = createStrictMock(Region.class);

         expect(deletedRegion.getRegionWidgets()).andReturn(movedWidgets);

         replay(deletedRegion);

         regions.add(deletedRegion);

-        

-        PageLayout prevLayout = createStrictMock(PageLayout.class);

+

+        PageLayout prevLayout = createStrictMock(PageLayoutImpl.class);

         expect(prevLayout.getNumberOfRegions()).andReturn(new Long(2)).anyTimes();

         replay(prevLayout);

-        

-        PageLayout layout = createStrictMock(PageLayout.class);

+

+        PageLayoutImpl layout = createStrictMock(PageLayoutImpl.class);

         expect(layout.getNumberOfRegions()).andReturn(new Long(1)).anyTimes();

         replay(layout);

-        

+

         regionRepository.delete(deletedRegion);

         expect(regionRepository.save(region)).andReturn(region);

         replay(regionRepository);

-        

+

         //create a strict mock that ensures that the appropriate setters are

         //called, rather than checking the return value from the function

-        Page curPage = createStrictMock(Page.class);

+        Page curPage = createStrictMock(PageImpl.class);

         expect(curPage.getPageLayout()).andReturn(prevLayout);

         expect(curPage.getRegions()).andReturn(regions);

         curPage.setName(newName);

         curPage.setPageLayout(layout);

         replay(curPage);

-        

+

         expect(pageRepository.get(PAGE_ID)).andReturn(curPage);

         expect(pageRepository.save(curPage)).andReturn(curPage);

         replay(pageRepository);

-        

+

         expect(pageLayoutRepository.getByPageLayoutCode(layoutName)).andReturn(layout);

         replay(pageLayoutRepository);

-        

+

         pageService.updatePage(PAGE_ID, newName, layoutName);

         assertThat(newLastWidgetColumn.size(), is (1));

-        

+

         verify(curPage);

     }

-    

-    

+

+

     @Test

     public void updatePage_removeRegion_moveWidgetToNonEmptyColumn() {

         String newName = "new page name";

         String layoutName = "layout name";

-        

-        

+

+

         RegionWidget widget = createStrictMock(RegionWidget.class);

         expect(widget.getRenderOrder()).andReturn(0).anyTimes();

         replay(widget);

         List<RegionWidget> newLastWidgetColumn = new ArrayList<RegionWidget>();

         newLastWidgetColumn.add(widget);

-        

+

         List<Region> regions = new ArrayList<Region>();

         Region region = createStrictMock(Region.class);

         expect(region.getRegionWidgets()).andReturn(newLastWidgetColumn).times(2);

         expect(region.getRenderOrder()).andReturn(1);

         replay(region);

         regions.add(region);

-        

-        

+

+

         widget = createStrictMock(RegionWidget.class);

         widget.setRegion(region);

         widget.setRenderOrder(1);

@@ -1162,50 +1185,50 @@
         replay(widget);

         List<RegionWidget> movedWidgets = new ArrayList<RegionWidget>();

         movedWidgets.add(widget);

-        

+

         Region deletedRegion = createStrictMock(Region.class);

         expect(deletedRegion.getRegionWidgets()).andReturn(movedWidgets);

         replay(deletedRegion);

         regions.add(deletedRegion);

-        

-        PageLayout prevLayout = createStrictMock(PageLayout.class);

+

+        PageLayout prevLayout = createStrictMock(PageLayoutImpl.class);

         expect(prevLayout.getNumberOfRegions()).andReturn(new Long(2)).anyTimes();

         replay(prevLayout);

-        

-        PageLayout layout = createStrictMock(PageLayout.class);

+

+        PageLayoutImpl layout = createStrictMock(PageLayoutImpl.class);

         expect(layout.getNumberOfRegions()).andReturn(new Long(1)).anyTimes();

         replay(layout);

-        

+

         regionRepository.delete(deletedRegion);

         expect(regionRepository.save(region)).andReturn(region);

         replay(regionRepository);

-        

+

         //create a strict mock that ensures that the appropriate setters are

         //called, rather than checking the return value from the function

-        Page curPage = createStrictMock(Page.class);

+        Page curPage = createStrictMock(PageImpl.class);

         expect(curPage.getPageLayout()).andReturn(prevLayout);

         expect(curPage.getRegions()).andReturn(regions);

         curPage.setName(newName);

         curPage.setPageLayout(layout);

         replay(curPage);

-        

+

         expect(pageRepository.get(PAGE_ID)).andReturn(curPage);

         expect(pageRepository.save(curPage)).andReturn(curPage);

         replay(pageRepository);

-        

+

         expect(pageLayoutRepository.getByPageLayoutCode(layoutName)).andReturn(layout);

         replay(pageLayoutRepository);

-        

+

         pageService.updatePage(PAGE_ID, newName, layoutName);

         assertThat(newLastWidgetColumn.size(), is (2));

         assertThat(newLastWidgetColumn.get(0).getRenderOrder(), is (0));

         assertThat(newLastWidgetColumn.get(1).getRenderOrder(), is (1));

-        

+

         verify(curPage);

     }

-    // private methods    

+    // private methods

     private void verifyPositions(int newPosition, RegionWidget widget, boolean sameRegion) {

-        assertThat(widget.getRenderOrder(), is(equalTo(newPosition)));        

+        assertThat(widget.getRenderOrder(), is(equalTo(newPosition)));

         assertOrder(originalRegion);

         assertThat(originalRegion.getRegionWidgets().contains(widget), is(sameRegion));

         if (!sameRegion) {

@@ -1214,7 +1237,7 @@
         }

     }

 

-    private void createMoveBetweenRegionsExpectations() {        

+    private void createMoveBetweenRegionsExpectations() {

         expect(regionRepository.get(TO_REGION_ID)).andReturn(targetRegion);

         expect(regionRepository.get(FROM_REGION_ID)).andReturn(originalRegion);

         expect(regionRepository.save(targetRegion)).andReturn(targetRegion);

@@ -1233,12 +1256,12 @@
             assertThat(region.getRegionWidgets().get(i).getRenderOrder(), is(equalTo(i)));

         }

     }

-    

+

     private List<Region> createEmptyRegionList(long numberOfRegions) {

         List<Region> regions = new ArrayList<Region>();

         int regionCount;

         for (regionCount = 0; regionCount < numberOfRegions; regionCount++) {

-              Region region = new Region();

+              Region region = new RegionImpl();

               regions.add(region);

         }

         return regions;

@@ -1250,20 +1273,20 @@
         final long CURRENT_PAGE_ID = 1L;

         final long TO_PAGE_ID = 2L;

 

-        Page currentPageValue = new Page();

+        Page currentPageValue = new PageImpl();

         currentPageValue.setRegions(new ArrayList<Region>());

         currentPageValue.getRegions().add(originalRegion);

         currentPageValue.getRegions().add(targetRegion);

 

-        Page toPageValue = new Page();

+        Page toPageValue = new PageImpl();

         toPageValue.setRegions(new ArrayList<Region>());

         toPageValue.getRegions().add(originalRegion);

         toPageValue.getRegions().add(targetRegion);

 

-        Region region = new Region();

+        Region region = new RegionImpl();

         region.setLocked(false);

-        

-        RegionWidget regionWidget = new RegionWidget(VALID_REGION_WIDGET_ID);

+

+        RegionWidget regionWidget = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         regionWidget.setRegion(region);

 

         expect(pageRepository.get(TO_PAGE_ID)).andReturn(toPageValue);

@@ -1286,12 +1309,12 @@
         final long CURRENT_PAGE_ID = 1L;

         final long TO_PAGE_ID = 2L;

 

-        Page currentPageValue = new Page();

+        Page currentPageValue = new PageImpl();

         currentPageValue.setRegions(new ArrayList<Region>());

         currentPageValue.getRegions().add(originalRegion);

         currentPageValue.getRegions().add(targetRegion);

 

-        Page toPageValue = new Page();

+        Page toPageValue = new PageImpl();

         toPageValue.setRegions(new ArrayList<Region>());

         toPageValue.getRegions().add(originalRegion);

         toPageValue.getRegions().add(targetRegion);

@@ -1309,20 +1332,20 @@
         final long CURRENT_PAGE_ID = 1L;

         final long TO_PAGE_ID = 2L;

 

-        Page currentPageValue = new Page();

+        Page currentPageValue = new PageImpl();

         currentPageValue.setRegions(new ArrayList<Region>());

         currentPageValue.getRegions().add(originalRegion);

         currentPageValue.getRegions().add(targetRegion);

 

-        Page toPageValue = new Page();

+        Page toPageValue = new PageImpl();

         toPageValue.setRegions(new ArrayList<Region>());

         toPageValue.getRegions().add(originalRegion);

         toPageValue.getRegions().add(targetRegion);

 

-        Region region = new Region();

+        Region region = new RegionImpl();

         region.setLocked(false);

 

-        RegionWidget regionWidget = new RegionWidget(VALID_REGION_WIDGET_ID);

+        RegionWidget regionWidget = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         regionWidget.setRegion(region);

         regionWidget.setLocked(true);

 

@@ -1341,20 +1364,20 @@
         final long CURRENT_PAGE_ID = 1L;

         final long TO_PAGE_ID = 2L;

 

-        Page currentPageValue = new Page();

+        Page currentPageValue = new PageImpl();

         currentPageValue.setRegions(new ArrayList<Region>());

         currentPageValue.getRegions().add(originalRegion);

         currentPageValue.getRegions().add(targetRegion);

 

-        Page toPageValue = new Page();

+        Page toPageValue = new PageImpl();

         toPageValue.setRegions(new ArrayList<Region>());

         toPageValue.getRegions().add(originalRegion);

         toPageValue.getRegions().add(targetRegion);

 

-        Region region = new Region();

+        Region region = new RegionImpl();

         region.setLocked(false);

 

-        RegionWidget regionWidget = new RegionWidget(VALID_REGION_WIDGET_ID);

+        RegionWidget regionWidget = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         regionWidget.setRegion(region);

         regionWidget.setLocked(true);

 

@@ -1373,20 +1396,20 @@
         final long CURRENT_PAGE_ID = 1L;

         final long TO_PAGE_ID = 2L;

 

-        Page currentPageValue = new Page();

+        Page currentPageValue = new PageImpl();

         currentPageValue.setRegions(new ArrayList<Region>());

         currentPageValue.getRegions().add(originalRegion);

         currentPageValue.getRegions().add(targetRegion);

 

-        Page toPageValue = new Page();

+        Page toPageValue = new PageImpl();

         toPageValue.setRegions(new ArrayList<Region>());

         toPageValue.getRegions().add(originalRegion);

         toPageValue.getRegions().add(targetRegion);

 

-        Region region = new Region();

+        Region region = new RegionImpl();

         region.setLocked(false);

 

-        RegionWidget regionWidget = new RegionWidget(VALID_REGION_WIDGET_ID);

+        RegionWidget regionWidget = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         regionWidget.setRegion(region);

         regionWidget.setLocked(true);

 

@@ -1395,5 +1418,5 @@
         replay(pageRepository,regionWidgetRepository);

 

         pageService.moveRegionWidgetToPage(VALID_REGION_WIDGET_ID, TO_PAGE_ID);

-    } 

+    }

 }

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceServiceTest.java
index 107281b..b129a44 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultPortalPreferenceServiceTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.service.impl;
 
 import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.impl.PortalPreferenceImpl;
 import org.apache.rave.portal.repository.PortalPreferenceRepository;
 import org.apache.rave.portal.service.PortalPreferenceService;
 import org.junit.Before;
@@ -30,13 +31,8 @@
 import java.util.List;
 import java.util.Map;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static junit.framework.Assert.*;
+import static org.easymock.EasyMock.*;
 
 /**
  * Test class for {@link DefaultPortalPreferenceService}
@@ -108,9 +104,8 @@
     public void testSaveKeyValue_new() {
         final String key = "foo";
         final String value = "bar";
-        PortalPreference fooBar = new PortalPreference(key, value);
-        PortalPreference fooBarSaved = new PortalPreference(key, value);
-        fooBarSaved.setEntityId(123L);
+        PortalPreference fooBar = new PortalPreferenceImpl(key, value);
+        PortalPreferenceImpl fooBarSaved = new PortalPreferenceImpl(key, value);
 
         expect(repository.getByKey(key)).andReturn(null).once();
         expect(repository.save(fooBar)).andReturn(fooBarSaved).once();
@@ -124,11 +119,8 @@
         final String key = "foo";
         final String value = "bar";
         final String newValue = "baz";
-        PortalPreference fooBar = new PortalPreference(key, value);
-        fooBar.setEntityId(123L);
-        PortalPreference fooBarSaved = new PortalPreference(key, newValue);
-        fooBarSaved.setEntityId(123L);
-
+        PortalPreferenceImpl fooBar = new PortalPreferenceImpl(key, value);
+        PortalPreferenceImpl fooBarSaved = new PortalPreferenceImpl(key, newValue);
         expect(repository.getByKey(key)).andReturn(fooBar).once();
         expect(repository.save(fooBar)).andReturn(fooBarSaved).once();
         replay(repository);
@@ -142,9 +134,8 @@
         List<String> values = new ArrayList<String>();
         values.add("bar");
         values.add("baz");
-        PortalPreference fooBar = new PortalPreference(key, values);
-        PortalPreference fooBarSaved = new PortalPreference(key, values);
-        fooBarSaved.setEntityId(123L);
+        PortalPreference fooBar = new PortalPreferenceImpl(key, values);
+        PortalPreferenceImpl fooBarSaved = new PortalPreferenceImpl(key, values);
 
         expect(repository.getByKey(key)).andReturn(null).once();
         expect(repository.save(fooBar)).andReturn(fooBarSaved).once();
@@ -162,10 +153,8 @@
         List<String> newValues = new ArrayList<String>();
         values.add("bar2");
         values.add("baz2");
-        PortalPreference fooBar = new PortalPreference(key, values);
-        fooBar.setEntityId(123L);
-        PortalPreference fooBarSaved = new PortalPreference(key, newValues);
-        fooBarSaved.setEntityId(123L);
+        PortalPreferenceImpl fooBar = new PortalPreferenceImpl(key, values);
+        PortalPreferenceImpl fooBarSaved = new PortalPreferenceImpl(key, newValues);
 
         expect(repository.getByKey(key)).andReturn(fooBar).once();
         expect(repository.save(fooBar)).andReturn(fooBarSaved).once();
@@ -177,8 +166,7 @@
     @Test
     public void testSavePreference() {
         PortalPreference title = titlePreference();
-        PortalPreference savedTitle = new PortalPreference("title", "Rave");
-        savedTitle.setEntityId(123L);
+        PortalPreferenceImpl savedTitle = new PortalPreferenceImpl("title", "Rave");
 
         expect(repository.save(title)).andReturn(savedTitle).once();
         replay(repository);
@@ -194,7 +182,7 @@
         colors.add("red");
         colors.add("yellow");
         colors.add("blue");
-        PortalPreference colorPref = new PortalPreference("colors", colors);
+        PortalPreference colorPref = new PortalPreferenceImpl("colors", colors);
 
         List<PortalPreference> preferences = new ArrayList<PortalPreference>();
         preferences.add(title);
@@ -204,6 +192,6 @@
     }
 
     private static PortalPreference titlePreference() {
-        return new PortalPreference("title", "Rave");
+        return new PortalPreferenceImpl("title", "Rave");
     }
 }
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetServiceTest.java
index cc40066..0689161 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultRegionWidgetServiceTest.java
@@ -22,9 +22,10 @@
 import org.apache.commons.lang.StringUtils;

 import org.apache.rave.portal.model.RegionWidget;

 import org.apache.rave.portal.model.RegionWidgetPreference;

+import org.apache.rave.portal.model.impl.RegionWidgetImpl;

+import org.apache.rave.portal.model.impl.RegionWidgetPreferenceImpl;

 import org.apache.rave.portal.repository.RegionWidgetRepository;

-import org.apache.rave.portal.service.impl.DefaultRegionWidgetService;

-import static org.hamcrest.CoreMatchers.*;

+import org.apache.rave.portal.service.RegionWidgetService;

 import org.junit.Before;

 import org.junit.Test;

 

@@ -33,8 +34,8 @@
 import java.util.List;

 import java.util.Map;

 

-import org.apache.rave.portal.service.RegionWidgetService;

 import static org.easymock.EasyMock.*;

+import static org.hamcrest.CoreMatchers.*;

 import static org.junit.Assert.assertThat;

 import static org.junit.Assert.assertTrue;

 

@@ -53,7 +54,7 @@
 

     @Test

     public void getRegionWidget_validId() {

-        final RegionWidget VALID_REGION_WIDGET = new RegionWidget(VALID_REGION_WIDGET_ID);

+        final RegionWidget VALID_REGION_WIDGET = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

 

         expect(regionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(VALID_REGION_WIDGET);

         replay(regionWidgetRepository);

@@ -71,7 +72,7 @@
 

     @Test

     public void saveRegionWidget() {

-        final RegionWidget VALID_REGION_WIDGET = new RegionWidget(VALID_REGION_WIDGET_ID);

+        final RegionWidget VALID_REGION_WIDGET = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

 

         expect(regionWidgetRepository.save(VALID_REGION_WIDGET)).andReturn(VALID_REGION_WIDGET);

         replay(regionWidgetRepository);

@@ -81,7 +82,7 @@
 

     @Test

     public void saveRegionWidgetPreferences() {

-        final RegionWidget VALID_REGION_WIDGET = new RegionWidget(VALID_REGION_WIDGET_ID);

+        final RegionWidget VALID_REGION_WIDGET = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         VALID_REGION_WIDGET.setPreferences(getTestExistingRegionWidgetPreferences());

 

         expect(regionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(VALID_REGION_WIDGET);

@@ -97,7 +98,7 @@
 

     @Test

     public void saveRegionWidgetPreference() {

-        final RegionWidget VALID_REGION_WIDGET = new RegionWidget(VALID_REGION_WIDGET_ID);

+        final RegionWidget VALID_REGION_WIDGET = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         VALID_REGION_WIDGET.setPreferences(getTestExistingRegionWidgetPreferences());

 

         expect(regionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(VALID_REGION_WIDGET).anyTimes();

@@ -105,9 +106,9 @@
         replay(regionWidgetRepository);

 

         //Add and update a preference.

-        RegionWidgetPreference newPreference = new RegionWidgetPreference(null, null, "age", "30");

+        RegionWidgetPreference newPreference = new RegionWidgetPreferenceImpl(null, "age", "30");

         RegionWidgetPreference savedNewPreference = regionWidgetService.saveRegionWidgetPreference(VALID_REGION_WIDGET_ID, newPreference);

-        RegionWidgetPreference updatedPreference = new RegionWidgetPreference(null, null, "color", "purple");

+        RegionWidgetPreference updatedPreference = new RegionWidgetPreferenceImpl(null, "color", "purple");

         RegionWidgetPreference savedUpdatedPreference = regionWidgetService.saveRegionWidgetPreference(VALID_REGION_WIDGET_ID, updatedPreference);

 

         //Make sure the new and updated preference got mixed in properly with the existing preferences.

@@ -121,7 +122,7 @@
     @Test

     public void saveRegionWidgetCollapsedState() {

         final boolean COLLAPSED = true;

-        RegionWidget regionWidget = new RegionWidget(VALID_REGION_WIDGET_ID);

+        RegionWidget regionWidget = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         

         expect(regionWidgetRepository.get(VALID_REGION_WIDGET_ID)).andReturn(regionWidget);                

         regionWidget.setCollapsed(COLLAPSED);

@@ -179,8 +180,8 @@
 

     private List<RegionWidgetPreference> getTestExistingRegionWidgetPreferences() {

         ArrayList<RegionWidgetPreference> regionWidgetPreferences = new ArrayList<RegionWidgetPreference>();

-        regionWidgetPreferences.add(new RegionWidgetPreference(1L, VALID_REGION_WIDGET_ID, "color", "blue"));

-        regionWidgetPreferences.add(new RegionWidgetPreference(2L, VALID_REGION_WIDGET_ID, "speed", "fast"));

+        regionWidgetPreferences.add(new RegionWidgetPreferenceImpl(VALID_REGION_WIDGET_ID, "color", "blue"));

+        regionWidgetPreferences.add(new RegionWidgetPreferenceImpl(VALID_REGION_WIDGET_ID, "speed", "fast"));

         return regionWidgetPreferences;

     }

 

@@ -188,7 +189,7 @@
         List<RegionWidgetPreference> regionWidgetPreferences = getTestExistingRegionWidgetPreferences();

         regionWidgetPreferences.remove(0);

         regionWidgetPreferences.get(0).setValue("slow");

-        regionWidgetPreferences.add(new RegionWidgetPreference(null, VALID_REGION_WIDGET_ID, "size", "small"));

+        regionWidgetPreferences.add(new RegionWidgetPreferenceImpl(VALID_REGION_WIDGET_ID, "size", "small"));

         return regionWidgetPreferences;

     }

 }
\ No newline at end of file
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultTagServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultTagServiceTest.java
index d0803e2..8c635b5 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultTagServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultTagServiceTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.service.impl;

 

 import org.apache.rave.portal.model.Tag;

+import org.apache.rave.portal.model.impl.TagImpl;

 import org.apache.rave.portal.repository.TagRepository;

 import org.apache.rave.portal.service.TagService;

 import org.junit.Before;

@@ -47,7 +48,7 @@
 

     @Test

     public void getTagById() {

-        Tag tag = createTag(1L, "test");

+        Tag tag = createTag("test");

         expect(repository.get(1L)).andReturn(tag);

         replay(repository);

         Tag sTag = service.getTagById(1L);

@@ -56,10 +57,9 @@
     }

 

 

-    private static Tag createTag(long id, String keyword) {

-        Tag tag = new Tag();

+    private static Tag createTag(String keyword) {

+        TagImpl tag = new TagImpl();

         tag.setKeyword(keyword);

-        tag.setEntityId(id);

         return tag;

     }

 

@@ -77,7 +77,7 @@
     @Test

     public void allTags() {

         List<Tag> tags = new ArrayList<Tag>();

-        Tag tag = createTag(1L, "test");

+        Tag tag = createTag("test");

         tags.add(tag);

         expect(repository.getAll()).andReturn(tags);

         replay(repository);

@@ -88,7 +88,7 @@
 

     @Test

     public void getByKeyword() {

-        Tag tag = createTag(1L, "test");

+        Tag tag = createTag("test");

         expect(repository.getByKeyword("test")).andReturn(tag);

         expect(repository.getByKeyword("TEST")).andReturn(tag);

         expect(repository.getByKeyword(" test")).andReturn(tag);

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java
index 026da53..e2bfbdb 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultUserServiceTest.java
@@ -20,6 +20,10 @@
 package org.apache.rave.portal.service.impl;
 
 import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.AuthorityImpl;
+import org.apache.rave.portal.model.impl.PageImpl;
+import org.apache.rave.portal.model.impl.PageTemplateImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.repository.*;
 import org.apache.rave.portal.service.UserService;
@@ -80,7 +84,7 @@
 
     @Test
     public void getAuthenticatedUser_validUser() {
-        final User authUser = new User(USER_ID);
+        final User authUser = new UserImpl(USER_ID);
         AbstractAuthenticationToken auth = createNiceMock(AbstractAuthenticationToken.class);
         expect(auth.getPrincipal()).andReturn(authUser).anyTimes();
         replay(auth);
@@ -119,7 +123,7 @@
 
     @Test
     public void setAuthenticatedUser_valid() {
-        final User authUser = new User(USER_ID);
+        final User authUser = new UserImpl(USER_ID);
         expect(userRepository.get(USER_ID)).andReturn(authUser).anyTimes();
         replay(userRepository);
 
@@ -131,8 +135,8 @@
 
     @Test
     public void setAuthenticatedUser_validRole() {
-        final User authUser = new User(USER_ID);
-        final Authority userRole = new Authority();
+        final User authUser = new UserImpl(USER_ID);
+        final Authority userRole = new AuthorityImpl();
         userRole.setAuthority("admin");
         authUser.addAuthority(userRole);
         expect(userRepository.get(USER_ID)).andReturn(authUser).anyTimes();
@@ -159,7 +163,7 @@
 
     @Test
     public void loadByUsername_valid() {
-        final User authUser = new User(USER_ID, USER_NAME);
+        final User authUser = new UserImpl(USER_ID, USER_NAME);
         expect(userRepository.getByUsername(USER_NAME)).andReturn(authUser).anyTimes();
         replay(userRepository);
 
@@ -187,7 +191,7 @@
 
      @Test
      public void getUserByEmail_valid() {
-          final User authUser=new User(USER_ID,USER_NAME);
+          final User authUser=new UserImpl(USER_ID,USER_NAME);
           authUser.setEmail(USER_EMAIL);
         expect(userRepository.getByUserEmail(USER_EMAIL)).andReturn(authUser).anyTimes();
         replay(userRepository);
@@ -208,8 +212,8 @@
 
     @Test
     public void getLimitedListOfUsers() {
-        User user1 = new User(123L, "john.doe.sr");
-        User user2 = new User(456L, "john.doe.jr");
+        User user1 = new UserImpl(123L, "john.doe.sr");
+        User user2 = new UserImpl(456L, "john.doe.jr");
         List<User> users = new ArrayList<User>();
         users.add(user1);
         users.add(user2);
@@ -229,8 +233,8 @@
     @Test
     public void getUsersByFreeTextSearch() {
         final String searchTerm = "Doe";
-        User user1 = new User(123L, "john.doe.sr");
-        User user2 = new User(456L, "john.doe.jr");
+        User user1 = new UserImpl(123L, "john.doe.sr");
+        User user2 = new UserImpl(456L, "john.doe.jr");
         List<User> users = new ArrayList<User>();
         users.add(user1);
         users.add(user2);
@@ -249,7 +253,7 @@
 
     @Test
     public void updateUserProfile() {
-        User user = new User(USER_ID, USER_NAME);
+        User user = new UserImpl(USER_ID, USER_NAME);
         expect(userRepository.save(user)).andReturn(user).once();
         replay(userRepository);
 
@@ -263,9 +267,8 @@
         final int NUM_COMMENTS = 33;
         final int NUM_RATINGS = 99;
         final int NUM_WIDGETS_OWNED = 4;
-        final int NUM_CATEGORIES = 2;
-        User user = new User(USER_ID, USER_NAME);
-        Page page = new Page(1L, user);
+        UserImpl user = new UserImpl(USER_ID, USER_NAME);
+        Page page = new PageImpl(1L, user);
         List<Page> pages = new ArrayList<Page>();
         pages.add(page);
 
@@ -275,7 +278,7 @@
         expect(widgetCommentRepository.deleteAll(USER_ID)).andReturn(NUM_COMMENTS);
         expect(widgetRatingRepository.deleteAll(USER_ID)).andReturn(NUM_RATINGS);
         expect(widgetRepository.unassignWidgetOwner(USER_ID)).andReturn( NUM_WIDGETS_OWNED);
-        expect(categoryRepository.removeFromCreatedOrModifiedFields(USER_ID)).andReturn(NUM_CATEGORIES);
+        expect(categoryRepository.removeFromCreatedOrModifiedFields(USER_ID)).andReturn( NUM_WIDGETS_OWNED);
         userRepository.delete(user);
         expectLastCall();
         replay(userRepository, pageRepository, widgetCommentRepository, widgetRatingRepository, widgetRepository, categoryRepository);
@@ -298,8 +301,8 @@
     @Test
     public void getAllByAddedWidget() {
         List<User> userList = new ArrayList<User>();
-        userList.add(new User());
-        userList.add(new User());
+        userList.add(new UserImpl());
+        userList.add(new UserImpl());
 
         List<Person> personList = new ArrayList<Person>();
         personList.add(userList.get(0).toPerson());
@@ -308,17 +311,18 @@
         expect(userRepository.getAllByAddedWidget(VALID_WIDGET_ID)).andReturn(userList);
         replay(userRepository);
 
-        assertThat(service.getAllByAddedWidget(VALID_WIDGET_ID), is(personList));
+        List<Person> allByAddedWidget = service.getAllByAddedWidget(VALID_WIDGET_ID);
+        assertThat(allByAddedWidget, is(equalTo(personList)));
 
         verify(userRepository);
     }
 
     @Test
     public void registerNewUser_valid(){
-        User user = new User();
+        User user = new UserImpl();
         expect(userRepository.save(user)).andReturn(user).once();
-        expect(pageTemplateRepository.getDefaultPage(PageType.PERSON_PROFILE)).andReturn(new PageTemplate()).once();
-        expect(pageRepository.createPageForUser(isA(User.class), isA(PageTemplate.class))).andReturn(new Page());
+        expect(pageTemplateRepository.getDefaultPage(PageType.PERSON_PROFILE)).andReturn(new PageTemplateImpl()).once();
+        expect(pageRepository.createPageForUser(isA(UserImpl.class), isA(PageTemplate.class))).andReturn(new PageImpl());
         replay(userRepository, pageTemplateRepository, pageRepository);
         service.registerNewUser(user);
         verify(userRepository, pageTemplateRepository, pageRepository);
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentServiceTest.java
index cef07c7..b6bc894 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetCommentServiceTest.java
@@ -15,20 +15,18 @@
  */
 package org.apache.rave.portal.service.impl;
 
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
 import org.apache.rave.portal.model.WidgetComment;
+import org.apache.rave.portal.model.impl.WidgetCommentImpl;
 import org.apache.rave.portal.repository.WidgetCommentRepository;
 import org.apache.rave.portal.service.WidgetCommentService;
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
 public class DefaultWidgetCommentServiceTest {
 
     private WidgetCommentRepository widgetCommentRepository;
@@ -43,8 +41,8 @@
 
     @Test
     public void getWidgetComment() {
-        WidgetComment comment = new WidgetComment();
-        comment.setEntityId(1L);
+        WidgetComment comment = new WidgetCommentImpl();
+        comment.setId(1L);
         expect(widgetCommentRepository.get(1L)).andReturn(comment);
         replay(widgetCommentRepository);
 
@@ -54,8 +52,8 @@
 
     @Test
     public void saveWidgetComment() {
-        WidgetComment comment = new WidgetComment();
-        comment.setEntityId(1L);
+        WidgetComment comment = new WidgetCommentImpl();
+        comment.setId(1L);
         expect(widgetCommentRepository.save(comment)).andReturn(comment);
         replay(widgetCommentRepository);
 
@@ -65,8 +63,8 @@
 
     @Test
     public void deleteWidgetComment() {
-        WidgetComment comment = new WidgetComment();
-        comment.setEntityId(1L);
+        WidgetComment comment = new WidgetCommentImpl();
+        comment.setId(1L);
         expect(widgetCommentRepository.get(1L)).andReturn(comment);
         widgetCommentRepository.delete(comment);
         replay(widgetCommentRepository);
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java
index 63da4d7..d50896a 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetRatingServiceTest.java
@@ -19,6 +19,7 @@
 

 package org.apache.rave.portal.service.impl;

 

+import org.apache.rave.portal.model.impl.WidgetRatingImpl;

 import org.apache.rave.portal.model.WidgetRating;

 import org.apache.rave.portal.repository.WidgetRatingRepository;

 import org.apache.rave.portal.service.WidgetRatingService;

@@ -45,7 +46,7 @@
 

     @Test

     public void testGetByWidgetIdAndUserId() {

-        WidgetRating widgetRating = new WidgetRating(1L, 2L, 3L, 5);

+        WidgetRating widgetRating = new WidgetRatingImpl(1L, 2L, 3L, 5);

         expect(repository.getByWidgetIdAndUserId(2L, 3L)).andReturn(widgetRating);

         replay(repository);

         final WidgetRating rating = service.getByWidgetIdAndUserId(2L, 3L);

@@ -55,7 +56,7 @@
 

     @Test

     public void updateScore() {

-        WidgetRating widgetRating = createMock(WidgetRating.class);

+        WidgetRating widgetRating = createMock(WidgetRatingImpl.class);

         widgetRating.setScore(10);

 

         expectLastCall().once();

@@ -68,7 +69,7 @@
 

     @Test

     public void saveWidgetRating_new() {

-        WidgetRating newRating = new WidgetRating();

+        WidgetRating newRating = new WidgetRatingImpl();

         newRating.setWidgetId(2L);

         newRating.setUserId(1L);

         newRating.setScore(10);

@@ -83,8 +84,8 @@
 

     @Test

     public void saveWidgetRating_existing() {

-        WidgetRating existingRating = new WidgetRating(1L, 1L, 1L, 5);

-        WidgetRating newRating = new WidgetRating();

+        WidgetRating existingRating = new WidgetRatingImpl(1L, 1L, 1L, 5);

+        WidgetRating newRating = new WidgetRatingImpl();

         newRating.setWidgetId(1L);

         newRating.setUserId(1L);

         newRating.setScore(10);

@@ -101,7 +102,7 @@
 

     @Test

     public void removeWidgetRating_existingRating() {

-        final WidgetRating widgetRating = new WidgetRating(1L, 1L, 1L, 5);

+        final WidgetRating widgetRating = new WidgetRatingImpl(1L, 1L, 1L, 5);

 

         expect(repository.getByWidgetIdAndUserId(1L, 1L)).andReturn(widgetRating);

         repository.delete(widgetRating);

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java
index 3f9f4a3..4350234 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetServiceTest.java
@@ -21,9 +21,11 @@
 
 import org.apache.rave.exception.DuplicateItemException;
 import org.apache.rave.portal.model.Category;
-import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.model.Widget;
 import org.apache.rave.portal.model.WidgetStatus;
+import org.apache.rave.portal.model.impl.CategoryImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.model.util.WidgetStatistics;
 import org.apache.rave.portal.repository.CategoryRepository;
@@ -74,8 +76,8 @@
 
     @Test
     public void getLimitedListOfWidgets() {
-        Widget widget1 = new Widget(1L, "http://example.com/widget1.xml");
-        Widget widget2 = new Widget(2L, "http://example.com/widget2.xml");
+        Widget widget1 = new WidgetImpl(1L, "http://example.com/widget1.xml");
+        Widget widget2 = new WidgetImpl(2L, "http://example.com/widget2.xml");
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget1);
         widgets.add(widget2);
@@ -92,9 +94,9 @@
 
     @Test
     public void getPublishedWidgets() {
-        Widget widget1 = new Widget(1L, "http://example.com/widget1.xml");
+        Widget widget1 = new WidgetImpl(1L, "http://example.com/widget1.xml");
         widget1.setWidgetStatus(WidgetStatus.PUBLISHED);
-        Widget widget2 = new Widget(2L, "http://example.com/widget2.xml");
+        Widget widget2 = new WidgetImpl(2L, "http://example.com/widget2.xml");
         widget2.setWidgetStatus(WidgetStatus.PUBLISHED);
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget1);
@@ -112,7 +114,7 @@
 
     @Test
     public void getWidget() {
-        Widget w = new Widget();
+        Widget w = new WidgetImpl();
         expect(widgetRepository.get(1L)).andReturn(w);
         replay(widgetRepository);
 
@@ -127,8 +129,8 @@
         int offset = 0;
         int pageSize = 10;
         int totalResults = 2;
-        Widget widget = new Widget();
-        widget.setEntityId(1L);
+        WidgetImpl widget = new WidgetImpl();
+        widget.setId(1L);
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget);
 
@@ -150,9 +152,9 @@
         int offset = 0;
         int pageSize = 10;
         int totalResults = 2;
-        Widget widget = new Widget();
+        WidgetImpl widget = new WidgetImpl();
         widget.setWidgetStatus(WidgetStatus.PUBLISHED);
-        widget.setEntityId(1L);
+        widget.setId(1L);
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget);
 
@@ -176,11 +178,11 @@
         int offset = 0;
         int pageSize = 10;
         int totalResults = 2;
-        Widget widget = new Widget();
+        WidgetImpl widget = new WidgetImpl();
         widget.setWidgetStatus(WidgetStatus.PUBLISHED);
         final String type = "OpenSocial";
         widget.setType(type);
-        widget.setEntityId(1L);
+        widget.setId(1L);
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget);
 
@@ -202,19 +204,19 @@
     public void getWidgetsByOwner() {
         final int offset = 0;
         final int pageSize = 10;
-        final User user = new User(5L);
-        expect(userRepository.get(user.getEntityId())).andReturn(user);
+        final UserImpl user = new UserImpl(5L);
+        expect(userRepository.get(user.getId())).andReturn(user);
         replay(userRepository);
 
         final List<Widget> widgets = new ArrayList<Widget>();
-        final Widget widget = new Widget(3L, "http://www.widgetsRus.com/");
+        final Widget widget = new WidgetImpl(3L, "http://www.widgetsRus.com/");
         widgets.add(widget);
 
         expect(widgetRepository.getCountByOwner(user, offset, pageSize)).andReturn(widgets.size());
         expect(widgetRepository.getByOwner(user, offset, pageSize)).andReturn(widgets);
         replay(widgetRepository);
 
-        SearchResult<Widget> result = widgetService.getWidgetsByOwner(user.getEntityId(), offset, pageSize);
+        SearchResult<Widget> result = widgetService.getWidgetsByOwner(user.getId(), offset, pageSize);
         assertNotNull(result);
         assertEquals(offset, result.getOffset());
         assertEquals(pageSize, result.getPageSize());
@@ -238,7 +240,7 @@
     public void getWidgetByUrl() {
         final String widgetUrl =
                 "http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.xml";
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         widget.setUrl(widgetUrl);
         expect(widgetRepository.getByUrl(widgetUrl)).andReturn(widget);
         replay(widgetRepository);
@@ -253,7 +255,7 @@
     public void isRegisteredWidget() {
         final String widgetUrl =
                 "http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.xml";
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         widget.setUrl(widgetUrl);
         expect(widgetRepository.getByUrl(widgetUrl)).andReturn(widget);
         replay(widgetRepository);
@@ -267,7 +269,7 @@
     public void isNotRegisteredWidget_() {
         final String widgetUrl =
                 "http://example.com/doesnotexistinrepository.xml";
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         widget.setUrl(widgetUrl);
         expect(widgetRepository.getByUrl(widgetUrl)).andReturn(null);
         replay(widgetRepository);
@@ -280,7 +282,7 @@
     @Test
     public void registerNewWidget() {
         final String widgetUrl = "http://example.com/newwidget.xml";
-        Widget widget = new Widget();
+        WidgetImpl widget = new WidgetImpl();
         widget.setUrl(widgetUrl);
         expect(widgetRepository.getByUrl(widgetUrl)).andReturn(null);
         expect(widgetRepository.save(widget)).andReturn(widget);
@@ -288,7 +290,7 @@
 
         Widget savedWidget = widgetService.registerNewWidget(widget);
         assertNotNull(savedWidget);
-        assertEquals(widget.getEntityId(), savedWidget.getEntityId());
+        assertEquals(widget.getId(), savedWidget.getId());
 
         verify(widgetRepository);
     }
@@ -297,7 +299,7 @@
     public void registerExistingWidgetAsNew() {
         final String widgetUrl =
                 "http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.xml";
-        Widget widget = new Widget();
+        WidgetImpl widget = new WidgetImpl();
         widget.setUrl(widgetUrl);
         expect(widgetRepository.getByUrl(widgetUrl)).andReturn(widget);
         replay(widgetRepository);
@@ -311,7 +313,7 @@
     public void updateWidget() {
         final String widgetUrl =
                 "http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.xml";
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         widget.setUrl(widgetUrl);
         expect(widgetRepository.save(widget)).andReturn(widget).once();
         replay(widgetRepository);
@@ -345,15 +347,15 @@
     public void getWidgetsByCategory_valid(){
         long id = 1L;
         int offset = 0;
-        int pageSize = 10; 
+        int pageSize = 10;
         String categoryText = "Social";
-        Widget w = new Widget();
+        Widget w = new WidgetImpl();
         List<Category> categories = new ArrayList<Category>();
-        Category c = new Category();
+        Category c = new CategoryImpl();
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(w);
         c.setWidgets(widgets);
-        c.setEntityId(id);
+        c.setId(id);
         c.setText(categoryText);
         categories.add(c);
         w.setCategories(categories);
@@ -363,7 +365,7 @@
         verify(categoryRepository);
         assertEquals("number of widgets", 1, result.getTotalResults());
         assertSame(w, result.getResultSet().get(0));
-        assertEquals(c.getEntityId(), result.getResultSet().get(0).getCategories().get(0).getEntityId());
+        assertEquals(c.getId(), result.getResultSet().get(0).getCategories().get(0).getId());
     }
 
 }
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetTagServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetTagServiceTest.java
index 50c75f3..d8a0bc3 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetTagServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/service/impl/DefaultWidgetTagServiceTest.java
@@ -15,8 +15,8 @@
  */

 package org.apache.rave.portal.service.impl;

 

-import org.apache.rave.portal.model.Tag;

-import org.apache.rave.portal.model.WidgetTag;

+import org.apache.rave.portal.model.impl.TagImpl;

+import org.apache.rave.portal.model.impl.WidgetTagImpl;

 import org.apache.rave.portal.repository.WidgetTagRepository;

 import org.apache.rave.portal.service.WidgetTagService;

 import org.junit.Before;

@@ -39,8 +39,7 @@
 

     @Test

     public void getWidgetTag() {

-        WidgetTag tag = new WidgetTag();

-        tag.setEntityId(1L);

+        WidgetTagImpl tag = new WidgetTagImpl();

         expect(widgetTagRepository.get(1L)).andReturn(tag);

         replay(widgetTagRepository);

 

@@ -52,9 +51,8 @@
     public void saveWidgetTag() {

         try {

 

-            WidgetTag wtag = new WidgetTag();

-            wtag.setEntityId(3L);

-            Tag tag = new Tag(4L, "test");

+            WidgetTagImpl wtag = new WidgetTagImpl();

+            TagImpl tag = new TagImpl();

             wtag.setTag(tag);

             expect(widgetTagRepository.save(wtag)).andReturn(wtag);

             replay(widgetTagRepository);

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceTest.java b/rave-components/rave-core/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceTest.java
index bb10849..67ad1ce 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceTest.java
+++ b/rave-components/rave-core/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceTest.java
@@ -21,7 +21,8 @@
 
 import org.apache.rave.exception.NotSupportedException;
 import org.apache.rave.portal.model.RegionWidget;
-import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.RegionWidgetImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.web.renderer.impl.DefaultRenderService;
 import org.apache.rave.portal.web.renderer.model.RenderContext;
 import org.junit.Before;
@@ -83,10 +84,10 @@
 
     @Test
     public void render_supported_foo() {
-        Widget w = new Widget();
+        WidgetImpl w = new WidgetImpl();
         w.setType(SUPPORTED_TYPE_1);
 
-        RegionWidget rw = new RegionWidget();
+        RegionWidget rw = new RegionWidgetImpl();
         rw.setWidget(w);
 
         expect(widgetRenderer1.render(rw, context)).andReturn(RENDERED_TYPE_1);
@@ -98,9 +99,9 @@
 
     @Test
     public void render_supported_bar() {
-        Widget w = new Widget();
+        WidgetImpl w = new WidgetImpl();
         w.setType(SUPPORTED_TYPE_2);
-        RegionWidget rw = new RegionWidget();
+        RegionWidget rw = new RegionWidgetImpl();
         rw.setWidget(w);
 
         expect(widgetRenderer2.render(rw, context)).andReturn(RENDERED_TYPE_2);
@@ -112,10 +113,10 @@
 
     @Test(expected = NotSupportedException.class)
     public void render_invalid() {
-        Widget w = new Widget();
+        WidgetImpl w = new WidgetImpl();
         w.setType("NONE");
 
-        RegionWidget rw = new RegionWidget();
+        RegionWidget rw = new RegionWidgetImpl();
         rw.setWidget(w);
 
         replayMocks();
diff --git a/rave-components/rave-core/src/test/resources/test_data.sql b/rave-components/rave-core/src/test/resources/test_data.sql
index 7d66e0b..49459e1 100644
--- a/rave-components/rave-core/src/test/resources/test_data.sql
+++ b/rave-components/rave-core/src/test/resources/test_data.sql
@@ -1003,18 +1003,18 @@
 set @next_portal_preference_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @portal_preference_seq);
 INSERT INTO portal_preference (entity_id, preference_key)
 values (@next_portal_preference_id, 'color');
-INSERT INTO portalpreference_values
+INSERT INTO JPAPORTALPREFERENCE_VALUES
 values (@next_portal_preference_id, 'red');
-INSERT INTO portalpreference_values
+INSERT INTO JPAPORTALPREFERENCE_VALUES
 values (@next_portal_preference_id, 'yellow');
-INSERT INTO portalpreference_values
+INSERT INTO JPAPORTALPREFERENCE_VALUES
 values (@next_portal_preference_id, 'blue');
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @portal_preference_seq;
 
 set @next_portal_preference_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @portal_preference_seq);
 INSERT INTO portal_preference (entity_id, preference_key)
 values (@next_portal_preference_id, 'title');
-INSERT INTO portalpreference_values
+INSERT INTO JPAPORTALPREFERENCE_VALUES
 values (@next_portal_preference_id, 'Rave');
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @portal_preference_seq;
 -- end portal preferences
diff --git a/rave-components/rave-jpa/pom.xml b/rave-components/rave-jpa/pom.xml
new file mode 100644
index 0000000..109f051
--- /dev/null
+++ b/rave-components/rave-jpa/pom.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+
+  $Id: pom.xml 1343841 2012-05-29 16:48:53Z mfranklin $
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>rave-components</artifactId>
+        <groupId>org.apache.rave</groupId>
+        <version>0.13-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>rave-jpa</artifactId>
+    <name>Apache Rave :: rave-jpa</name>
+    <description>Apache Rave JPA Persistence Implementation</description>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.rave</groupId>
+            <artifactId>rave-commons</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-context</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-orm</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.springframework.security</groupId>
+                    <artifactId>spring-security-web</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.rave</groupId>
+            <artifactId>rave-core</artifactId>
+        </dependency>
+
+        <!-- Spring -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-orm</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-web</artifactId>
+        </dependency>
+
+        <!-- Jackson JSON Mapper -->
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>1.8.1</version>
+        </dependency>
+
+        <!-- JSON Support -->
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20090211</version>
+        </dependency>
+
+        <!--Persistence-->
+        <dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- Logging -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.ibm.icu</groupId>
+            <artifactId>icu4j</artifactId>
+        </dependency>
+
+        <!--  Captcha -->
+        <dependency>
+            <groupId>net.tanesha.recaptcha4j</groupId>
+            <artifactId>recaptcha4j</artifactId>
+        </dependency>
+
+        <!-- mail -->
+        <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+        </dependency>
+
+
+        <!-- Test -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <defaultGoal>install</defaultGoal>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>openjpa-maven-plugin</artifactId>
+                <version>1.2</version>
+                <configuration>
+                    <includes>org/apache/rave/portal/model/*.class</includes>
+                    <includes>org/apache/rave/portal/repository/JpaApplicationDataRepository$JpaSerializableApplicationData.class</includes>
+                    <addDefaultConstructor>true</addDefaultConstructor>
+                    <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>enhancer</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>enhance</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <exclusions>
+                            <exclusion>
+                                <groupId>xerces</groupId>
+                                <artifactId>xmlParserAPIs</artifactId>
+                            </exclusion>
+                        </exclusions>
+                        <groupId>org.apache.openjpa</groupId>
+                        <artifactId>openjpa</artifactId>
+                        <version>${openjpa.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaAddress.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaAddress.java
new file mode 100644
index 0000000..327ef0f
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaAddress.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import javax.persistence.*;
+
+/**
+ */
+@Entity
+@Access(AccessType.FIELD)
+@NamedQueries(value = {
+        @NamedQuery(name = JpaAddress.FIND_BY_STREET_CITY_COUNTRY, query = "select a from JpaAddress a where a.streetAddress=:street and a.locality=:city and a.country=:country")
+})
+@Table(name = "address")
+public class JpaAddress implements Address {
+
+    public static final String FIND_BY_STREET_CITY_COUNTRY = "findByStreetCityCountry";
+    public static final String STREET_PARAM = "street";
+    public static final String CITY_PARAM = "city";
+    public static final String COUNTRY_PARAM = "country";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "addressIdGenerator")
+    @TableGenerator(name = "addressIdGenerator", table = "RAVE_SHINDIG_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "address", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic
+    @Column(name = "country", length = 255)
+    private String country;
+
+    @Basic
+    @Column(name = "latitude")
+    private Float latitude;
+
+    @Basic
+    @Column(name = "longitude")
+    private Float longitude;
+
+    @Basic
+    @Column(name = "locality", length = 255)
+    private String locality;
+
+    @Basic
+    @Column(name = "postal_code", length = 255)
+    private String postalCode;
+
+    @Basic
+    @Column(name = "region", length = 255)
+    private String region;
+
+    @Basic
+    @Column(name = "street_address", length = 255)
+    private String streetAddress;
+
+    @Basic
+    @Column(name = "qualifier", length = 255)
+    private String qualifier;
+
+    @Basic
+    @Column(name = "formatted", length = 255)
+    private String formatted;
+
+    @Basic
+    @Column(name = "primary_address")
+    private Boolean primary;
+
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public String getCountry() {
+        return country;
+    }
+
+    @Override
+    public void setCountry(String country) {
+        this.country = country;
+    }
+
+    @Override
+    public Float getLatitude() {
+        return latitude;
+    }
+
+    @Override
+    public void setLatitude(Float latitude) {
+        this.latitude = latitude;
+    }
+
+    @Override
+    public Float getLongitude() {
+        return longitude;
+    }
+
+    @Override
+    public void setLongitude(Float longitude) {
+        this.longitude = longitude;
+    }
+
+    @Override
+    public String getLocality() {
+        return locality;
+    }
+
+    @Override
+    public void setLocality(String locality) {
+        this.locality = locality;
+    }
+
+    @Override
+    public String getPostalCode() {
+        return postalCode;
+    }
+
+    @Override
+    public void setPostalCode(String postalCode) {
+        this.postalCode = postalCode;
+    }
+
+    @Override
+    public String getRegion() {
+        return region;
+    }
+
+    @Override
+    public void setRegion(String region) {
+        this.region = region;
+    }
+
+    @Override
+    public String getStreetAddress() {
+        return streetAddress;
+    }
+
+    @Override
+    public void setStreetAddress(String streetAddress) {
+        this.streetAddress = streetAddress;
+    }
+
+    @Override
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    @Override
+    public void setQualifier(String qualifier) {
+        this.qualifier = qualifier;
+    }
+
+    @Override
+    public String getFormatted() {
+        return formatted;
+    }
+
+    @Override
+    public void setFormatted(String formatted) {
+        this.formatted = formatted;
+    }
+
+    @Override
+    public Boolean getPrimary() {
+        return primary;
+    }
+
+    @Override
+    public void setPrimary(Boolean primary) {
+        this.primary = primary;
+    }
+}
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/model/ApplicationData.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaApplicationData.java
similarity index 72%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/model/ApplicationData.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaApplicationData.java
index be935c6..6901caf 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/model/ApplicationData.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaApplicationData.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations

  * under the License.

  */

-package org.apache.rave.opensocial.model;

+package org.apache.rave.portal.model;

 

 import org.apache.rave.persistence.BasicEntity;

 

@@ -26,12 +26,12 @@
 @Entity

 @Table(name = "application_data")

 @NamedQueries(value = {

-        @NamedQuery(name = ApplicationData.FIND_BY_USER_IDS_AND_APP_ID, query = "select a from ApplicationData a " +

-                "where a.userId IN :" + ApplicationData.USER_IDS_PARAM + " AND a.appUrl = :" + ApplicationData.APP_URL_PARAM),

-        @NamedQuery(name = ApplicationData.FIND_BY_USER_ID_AND_APP_ID, query = "select a from ApplicationData a " +

-                "where a.userId = :" + ApplicationData.USER_ID_PARAM + " AND a.appUrl = :" + ApplicationData.APP_URL_PARAM)

+        @NamedQuery(name = JpaApplicationData.FIND_BY_USER_IDS_AND_APP_ID, query = "select a from JpaApplicationData a " +

+                "where a.userId IN :" + JpaApplicationData.USER_IDS_PARAM + " AND a.appUrl = :" + JpaApplicationData.APP_URL_PARAM),

+        @NamedQuery(name = JpaApplicationData.FIND_BY_USER_ID_AND_APP_ID, query = "select a from JpaApplicationData a " +

+                "where a.userId = :" + JpaApplicationData.USER_ID_PARAM + " AND a.appUrl = :" + JpaApplicationData.APP_URL_PARAM)

 })

-public class ApplicationData implements BasicEntity {

+public class JpaApplicationData implements BasicEntity, ApplicationData {

     public static final String FIND_BY_USER_IDS_AND_APP_ID = "ApplicationData.findByUserIdsAndAppId";

     public static final String FIND_BY_USER_ID_AND_APP_ID = "ApplicationData.findByUserIdAndAppId";

 

@@ -58,44 +58,62 @@
     @Transient

     private Map<String, String> data;

 

-    public ApplicationData() {

+    public JpaApplicationData() {

     }

 

-    public ApplicationData(Long entityId, String userId, String appUrl, Map<String, String> data) {

+    public JpaApplicationData(Long entityId, String userId, String appUrl, Map<String, String> data) {

         this.entityId = entityId;

         this.userId = userId;

         this.appUrl = appUrl;

         this.data = data;

     }

 

+    @Override

+    public Long getId() {

+        return getEntityId();

+    }

+

+    @Override

+    public void setId(Long id) {

+        setEntityId(id);

+    }

+

+    @Override

     public Long getEntityId() {

         return entityId;

     }

 

+    @Override

     public void setEntityId(Long entityId) {

         this.entityId = entityId;

     }

 

+    @Override

     public String getUserId() {

         return userId;

     }

 

+    @Override

     public void setUserId(String userId) {

         this.userId = userId;

     }

 

+    @Override

     public String getAppUrl() {

         return appUrl;

     }

 

+    @Override

     public void setAppUrl(String appUrl) {

         this.appUrl = appUrl;

     }

 

+    @Override

     public Map<String, String> getData() {

         return data;

     }

 

+    @Override

     public void setData(Map<String, String> data) {

         this.data = data;

     }

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaAuthority.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaAuthority.java
new file mode 100644
index 0000000..08097c5
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaAuthority.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+import org.springframework.security.core.GrantedAuthority;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * The {@link GrantedAuthority} a {@link JpaUser} can have
+ */
+@Entity
+@Table(name = "granted_authority")
+@Access(AccessType.FIELD)
+@NamedQueries({
+        @NamedQuery(name = JpaAuthority.GET_BY_AUTHORITY_NAME, query = "SELECT a FROM JpaAuthority a WHERE a.authority = :authority"),
+        @NamedQuery(name = JpaAuthority.GET_ALL, query = "SELECT a FROM JpaAuthority a"),
+        @NamedQuery(name = JpaAuthority.GET_ALL_DEFAULT, query = "SELECT a FROM JpaAuthority a WHERE a.defaultForNewUser = true"),
+        @NamedQuery(name = JpaAuthority.COUNT_ALL, query = "SELECT COUNT(a) FROM JpaAuthority a")
+})
+public class JpaAuthority implements BasicEntity, Serializable, Authority {
+
+    private static final long serialVersionUID = 463209366149842862L;
+
+    public static final String PARAM_AUTHORITY_NAME = "authority";
+    public static final String GET_BY_AUTHORITY_NAME = "Authority.GetByAuthorityName";
+    public static final String GET_ALL = "Authority.GetAll";
+    public static final String GET_ALL_DEFAULT = "Authority.GetAllDefault";
+    public static final String COUNT_ALL = "Authority.CountAll";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "grantedAuthorityIdGenerator")
+    @TableGenerator(name = "grantedAuthorityIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "granted_authority", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic
+    @Column(name = "authority", unique = true)
+    private String authority;
+
+    @ManyToMany(mappedBy = "authorities", fetch = FetchType.LAZY)
+    private List<JpaUser> users;
+    
+    @Basic
+    @Column(name = "default_for_new_user")
+    private boolean defaultForNewUser;
+
+    /**
+     * Default constructor, needed for JPA
+     */
+    public JpaAuthority() {
+        this.users = new ArrayList<JpaUser>();
+    }
+
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public String getAuthority() {
+        return authority;
+    }
+
+    @Override
+    public void setAuthority(String authority) {
+        this.authority = authority;
+    }
+    
+    @Override
+    public boolean isDefaultForNewUser() {
+        return defaultForNewUser;
+    }    
+    
+    @Override
+    public void setDefaultForNewUser(boolean defaultForNewUser) {
+        this.defaultForNewUser = defaultForNewUser;
+    }    
+
+    @Override
+    public Collection<User> getUsers() {
+        return ConvertingListProxyFactory.createProxyList(User.class, users);
+    }
+
+    @Override
+    public void addUser(User user) {
+        if (!this.getUsers().contains(user)) {
+            this.getUsers().add(user);
+        }
+        if (!user.getAuthorities().contains(this)) {
+            user.addAuthority(this);
+        }
+    }
+
+    @Override
+    public void removeUser(User user) {
+        if (this.getUsers().contains(user)) {
+            this.getUsers().remove(user);
+        }
+    }
+
+    @PreRemove
+    public void preRemove() {
+        for (JpaUser user : users) {
+            user.removeAuthority(this);
+        }
+        this.users = null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        JpaAuthority authority = (JpaAuthority) o;
+
+        if (entityId != null ? !entityId.equals(authority.entityId) : authority.entityId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return entityId != null ? entityId.hashCode() : 0;
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaCategory.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaCategory.java
new file mode 100644
index 0000000..31b1c03
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaCategory.java
@@ -0,0 +1,205 @@
+/*

+ * Copyright 2011 The Apache Software Foundation.

+ *

+ * 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.rave.portal.model;

+

+import org.apache.rave.persistence.BasicEntity;

+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;

+import org.apache.rave.portal.model.conversion.JpaConverter;

+import org.codehaus.jackson.annotate.JsonIgnore;

+

+import javax.persistence.*;

+import javax.xml.bind.annotation.XmlRootElement;

+import java.io.Serializable;

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.List;

+

+

+@Entity

+@Table(name = "category")

+@Access(AccessType.FIELD)

+@XmlRootElement

+@NamedQueries({

+        @NamedQuery(name = JpaCategory.GET_ALL, query = "select c from JpaCategory c order by c.text")

+})

+public class JpaCategory implements BasicEntity, Serializable, Category {

+    // constants for JPA query names

+    public static final String GET_ALL = "Category.getAll";

+

+    @Id

+    @Column(name = "entity_id")

+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "categoryIdGenerator")

+    @TableGenerator(name = "categoryIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

+                    valueColumnName = "SEQ_COUNT", pkColumnValue = "category",

+                    allocationSize = 1, initialValue = 1)

+    private Long entityId;

+

+    @Basic

+    @Column(name = "text", unique = true)

+    private String text;

+

+    @OneToOne(fetch=FetchType.EAGER)

+    @JoinColumn(name="created_user_id")

+    private JpaUser createdUser;

+

+    @Basic

+    @Column(name ="created_date")

+    @Temporal(javax.persistence.TemporalType.TIMESTAMP)

+    private Date createdDate;

+

+

+    @OneToOne(fetch=FetchType.EAGER)

+    @JoinColumn(name="last_modified_user_id")

+    private JpaUser lastModifiedUser;

+

+    @Basic

+    @Column(name ="last_modified_date")

+    @Temporal(javax.persistence.TemporalType.TIMESTAMP)

+    private Date lastModifiedDate;

+

+    @ManyToMany(fetch = FetchType.EAGER)

+    @JoinTable(name="widget_category",

+               joinColumns=@JoinColumn(name="category_id", referencedColumnName = "entity_id"),

+               inverseJoinColumns=@JoinColumn(name="widget_id", referencedColumnName = "entity_id")

+    )

+    @OrderBy("title")

+    private List<JpaWidget> widgets;

+

+    public JpaCategory() {

+

+    }

+

+    public JpaCategory(Long entityId, String text, User createdUser, Date createdDate, User lastModifiedUser, Date lastModifiedDate) {

+        this.entityId = entityId;

+        this.text = text;

+        this.setCreatedUser(createdUser);

+        this.createdDate = createdDate;

+        this.setLastModifiedUser(lastModifiedUser);

+        this.lastModifiedDate = lastModifiedDate;

+    }

+

+    @Override

+    public Long getEntityId() {

+        return entityId;

+    }

+

+    @Override

+    public void setEntityId(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    @Override

+    public Long getId() {

+        return getEntityId();

+    }

+

+    @Override

+    public void setId(Long id) {

+        setEntityId(id);

+    }

+

+    @Override

+    public String getText() {

+        return text;

+    }

+

+    @Override

+    public void setText(String text) {

+        this.text = text;

+    }

+

+    @Override

+    public User getCreatedUser() {

+        return createdUser;

+    }

+

+    @Override

+    public void setCreatedUser(User createdUser) {

+        this.createdUser = JpaConverter.getInstance().convert(createdUser, User.class);

+    }

+

+    @Override

+    public Date getCreatedDate() {

+        return createdDate;

+    }

+

+    @Override

+    public void setCreatedDate(Date createdDate) {

+        this.createdDate = createdDate;

+    }

+

+    @Override

+    public User getLastModifiedUser() {

+        return lastModifiedUser;

+    }

+

+    @Override

+    public void setLastModifiedUser(User lastModifiedUser) {

+        this.lastModifiedUser = JpaConverter.getInstance().convert(lastModifiedUser, User.class);

+    }

+

+    @Override

+    public Date getLastModifiedDate() {

+        return lastModifiedDate;

+    }

+

+    @Override

+    public void setLastModifiedDate(Date lastModifiedDate) {

+        this.lastModifiedDate = lastModifiedDate;

+    }

+

+    @JsonIgnore

+    @Override

+    public List<Widget> getWidgets() {

+        return ConvertingListProxyFactory.createProxyList(Widget.class, widgets);

+    }

+

+    @Override

+    public void setWidgets(List<Widget> widgets) {

+        if(this.widgets == null) {

+            this.widgets = new ArrayList<JpaWidget>();

+        }

+        //Ensure that all operations go through the conversion proxy

+        this.getWidgets().clear();

+        if (widgets != null) {

+            this.getWidgets().addAll(widgets);

+        }

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (this == obj) return true;

+        if (obj == null || getClass() != obj.getClass()) return false;

+        JpaCategory category = (JpaCategory) obj;

+        if (entityId != null ? !entityId.equals(category.entityId) : category.entityId != null) return false;

+        return true;

+    }

+

+    @Override

+    public int hashCode() {

+        int hash = 7;

+        hash = 79 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);

+        return hash;

+    }

+

+    @Override

+    public String toString() {

+        return "Category{" +

+                "entityId=" + entityId +

+                ", text='" + text + '\'' +

+                '}';

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaGroup.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaGroup.java
new file mode 100644
index 0000000..ea59c4a
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaGroup.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+import org.apache.rave.portal.model.conversion.JpaConverter;
+import org.apache.rave.portal.model.conversion.JpaGroupConverter;
+import org.apache.rave.portal.model.conversion.JpaPersonConverter;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a group in the social database. The assumption in this object is that groups are
+ * associated with individuals and are used by those individuals to manage people.
+ */
+@Entity
+@Access(AccessType.FIELD)
+@Table(name = "groups")
+@NamedQueries(
+        @NamedQuery(name = JpaGroup.FIND_BY_TITLE, query="select g from JpaGroup g where g.title = :groupId")
+)
+public class JpaGroup implements BasicEntity, Group {
+
+    public static final String FIND_BY_TITLE = "Group.findById";
+    public static final String GROUP_ID_PARAM = "groupId";
+
+    /**
+     * The internal object ID used for references to this object. Should be generated by the
+     * underlying storage mechanism
+     */
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "groupIdGenerator")
+    @TableGenerator(name = "groupIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "groups", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic
+    @Column(name = "title", unique = true)
+    private String title;
+
+    @Basic
+    @Column(name = "description")
+    private String description;
+
+    @ManyToOne
+    @JoinColumn(name = "owner_id", referencedColumnName = "entity_id")
+    private JpaPerson owner;
+
+
+    @ManyToMany(fetch = FetchType.EAGER, mappedBy="groups")
+    private List<JpaPerson> members;
+
+    public JpaPerson getOwner() {
+        return owner;
+    }
+
+    public void setOwner(Person owner) {
+        this.owner = JpaConverter.getInstance().convert(owner, Person.class);
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public List<Person> getMembers() {
+        return ConvertingListProxyFactory.createProxyList(Person.class, members);
+    }
+
+    public void setMembers(List<Person> members) {
+        if(this.members == null) {
+            this.members = new ArrayList<JpaPerson>();
+        }
+        this.getMembers().clear();
+        if(members != null) {
+            this.getMembers().addAll(members);
+        }
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title  = title;
+    }
+
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+}
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOAuthConsumerStore.java
similarity index 88%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOAuthConsumerStore.java
index 3d139ec..888cae2 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOAuthConsumerStore.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.rave.gadgets.oauth.model;
+package org.apache.rave.portal.model;
 
 import org.apache.rave.persistence.BasicEntity;
 
@@ -60,10 +60,10 @@
 @Table(name = "oauth_consumer_store",
         uniqueConstraints = @UniqueConstraint(columnNames = {"gadget_uri", "service_name"}))
 @NamedQueries(value = {
-        @NamedQuery(name = OAuthConsumerStore.FIND_BY_URI_AND_SERVICE_NAME,
-                query = "SELECT cs FROM OAuthConsumerStore cs WHERE cs.gadgetUri = :gadgetUriParam AND cs.serviceName = :serviceNameParam")
+        @NamedQuery(name = JpaOAuthConsumerStore.FIND_BY_URI_AND_SERVICE_NAME,
+                query = "SELECT cs FROM JpaOAuthConsumerStore cs WHERE cs.gadgetUri = :gadgetUriParam AND cs.serviceName = :serviceNameParam")
         })
-public class OAuthConsumerStore implements BasicEntity {
+public class JpaOAuthConsumerStore implements BasicEntity, OAuthConsumerStore {
 
     public static final String FIND_BY_URI_AND_SERVICE_NAME = "OAuthConsumerStore.findByUriAndServiceName";
     public static final String GADGET_URI_PARAM = "gadgetUriParam";
@@ -72,13 +72,6 @@
     private static final int HASH_INCREASE = 67;
 
     /**
-     * enum of KeyType's
-     */
-    public static enum KeyType {
-        HMAC_SYMMETRIC, RSA_PRIVATE, PLAINTEXT
-    }
-
-    /**
      * The internal object ID used for references to this object.
      */
     @Id
@@ -135,6 +128,22 @@
     @Column(name = "callback_url")
     private String callbackUrl;
 
+    /*
+    * {@inheritDoc}
+    */
+    @Override
+    public Long getId() {
+        return getEntityId();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setId(Long id) {
+        setEntityId(id);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -151,58 +160,72 @@
         this.entityId = entityId;
     }
 
+    @Override
     public String getGadgetUri() {
         return gadgetUri;
     }
 
+    @Override
     public void setGadgetUri(String gadgetUri) {
         this.gadgetUri = gadgetUri;
     }
 
+    @Override
     public String getServiceName() {
         return serviceName;
     }
 
+    @Override
     public void setServiceName(String serviceName) {
         this.serviceName = serviceName;
     }
 
+    @Override
     public String getConsumerKey() {
         return consumerKey;
     }
 
+    @Override
     public void setConsumerKey(String consumerKey) {
         this.consumerKey = consumerKey;
     }
 
+    @Override
     public String getConsumerSecret() {
         return consumerSecret;
     }
 
+    @Override
     public void setConsumerSecret(String consumerSecret) {
         this.consumerSecret = consumerSecret;
     }
 
+    @Override
     public KeyType getKeyType() {
         return keyType;
     }
 
+    @Override
     public void setKeyType(KeyType keyType) {
         this.keyType = keyType;
     }
 
+    @Override
     public String getKeyName() {
         return keyName;
     }
 
+    @Override
     public void setKeyName(String keyName) {
         this.keyName = keyName;
     }
 
+    @Override
     public String getCallbackUrl() {
         return callbackUrl;
     }
 
+    @Override
     public void setCallbackUrl(String callbackUrl) {
         this.callbackUrl = callbackUrl;
     }
@@ -215,7 +238,7 @@
         if (getClass() != obj.getClass()) {
             return false;
         }
-        final OAuthConsumerStore other = (OAuthConsumerStore) obj;
+        final JpaOAuthConsumerStore other = (JpaOAuthConsumerStore) obj;
         if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
             return false;
         }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOAuthTokenInfo.java
similarity index 86%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOAuthTokenInfo.java
index f7a47e4..e759bdf 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOAuthTokenInfo.java
@@ -17,11 +17,9 @@
  * under the License.
  */
 
-package org.apache.rave.gadgets.oauth.model;
+package org.apache.rave.portal.model;
 
 import org.apache.rave.persistence.BasicEntity;
-import org.apache.shindig.auth.SecurityToken;
-import org.apache.shindig.gadgets.oauth.OAuthStore;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
@@ -39,15 +37,10 @@
 @Entity
 @Table(name = "oauth_token_info")
 @NamedQueries(value = {
-        @NamedQuery(name = OAuthTokenInfo.FIND_OAUTH_TOKEN_INFO,
-                query = "SELECT ti FROM OAuthTokenInfo ti WHERE ti.userId = :userIdParam AND ti.appUrl = :appUrlParam AND ti.moduleId = :moduleIdParam AND ti.tokenName = :tokenNameParam AND ti.serviceName = :serviceNameParam")
+        @NamedQuery(name = JpaOAuthTokenInfo.FIND_OAUTH_TOKEN_INFO,
+                query = "SELECT ti FROM JpaOAuthTokenInfo ti WHERE ti.userId = :userIdParam AND ti.appUrl = :appUrlParam AND ti.moduleId = :moduleIdParam AND ti.tokenName = :tokenNameParam AND ti.serviceName = :serviceNameParam")
 })
-public class OAuthTokenInfo implements BasicEntity {
-
-    /**
-     * @see {@link org.apache.shindig.social.core.oauth.OAuthSecurityToken#getModuleId()}
-     */
-    public static final String MODULE_ID = "NOT_USED";
+public class JpaOAuthTokenInfo implements BasicEntity, OAuthTokenInfo {
 
     /**
      * Named query identifier to find {@link OAuthTokenInfo}
@@ -120,12 +113,8 @@
     private String userId;
 
 
-    public OAuthTokenInfo() {
-        super();
-    }
-
-    public OAuthTokenInfo(SecurityToken securityToken, String serviceName,
-                          String tokenName, OAuthStore.TokenInfo tokenInfo) {
+/*    public JpaOAuthTokenInfo(SecurityToken securityToken, String serviceName,
+                             String tokenName, OAuthStore.TokenInfo tokenInfo) {
         this.setAccessToken(tokenInfo.getAccessToken());
         this.setAppUrl(securityToken.getAppUrl());
         this.setModuleId(MODULE_ID);
@@ -135,6 +124,16 @@
         this.setTokenName(tokenName);
         this.setTokenSecret(tokenInfo.getTokenSecret());
         this.setUserId(securityToken.getViewerId());
+    }*/
+
+    @Override
+    public Long getId() {
+        return getEntityId();
+    }
+
+    @Override
+    public void setId(Long id) {
+        setEntityId(id);
     }
 
     @Override
@@ -147,74 +146,92 @@
         this.entityId = entityId;
     }
 
+    @Override
     public String getAccessToken() {
         return accessToken;
     }
 
+    @Override
     public void setAccessToken(String accessToken) {
         this.accessToken = accessToken;
     }
 
+    @Override
     public String getTokenSecret() {
         return tokenSecret;
     }
 
+    @Override
     public void setTokenSecret(String tokenSecret) {
         this.tokenSecret = tokenSecret;
     }
 
+    @Override
     public String getSessionHandle() {
         return sessionHandle;
     }
 
+    @Override
     public void setSessionHandle(String sessionHandle) {
         this.sessionHandle = sessionHandle;
     }
 
+    @Override
     public long getTokenExpireMillis() {
         return tokenExpireMillis;
     }
 
+    @Override
     public void setTokenExpireMillis(long tokenExpireMillis) {
         this.tokenExpireMillis = tokenExpireMillis;
     }
 
+    @Override
     public String getAppUrl() {
         return appUrl;
     }
 
+    @Override
     public void setAppUrl(String appUrl) {
         this.appUrl = appUrl;
     }
 
+    @Override
     public String getModuleId() {
         return moduleId;
     }
 
+    @Override
     public void setModuleId(String moduleId) {
         this.moduleId = moduleId;
     }
 
+    @Override
     public String getServiceName() {
         return serviceName;
     }
 
+    @Override
     public void setServiceName(String serviceName) {
         this.serviceName = serviceName;
     }
 
+    @Override
     public String getTokenName() {
         return tokenName;
     }
 
+    @Override
     public void setTokenName(String tokenName) {
         this.tokenName = tokenName;
     }
 
+    @Override
     public String getUserId() {
         return userId;
     }
 
+    @Override
     public void setUserId(String userId) {
         this.userId = userId;
     }
@@ -227,7 +244,7 @@
         if (getClass() != obj.getClass()) {
             return false;
         }
-        final OAuthTokenInfo other = (OAuthTokenInfo) obj;
+        final JpaOAuthTokenInfo other = (JpaOAuthTokenInfo) obj;
         if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
             return false;
         }
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOrganization.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOrganization.java
new file mode 100644
index 0000000..7a4ce6d
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaOrganization.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.JpaConverter;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ */
+@Entity
+@Access(AccessType.FIELD)
+@NamedQueries(value = {
+        @NamedQuery(name = JpaOrganization.FIND_BY_NAME, query = "select o from JpaOrganization o where o.name like :name")
+})
+@Table(name = "organization")
+public class JpaOrganization implements BasicEntity, Organization {
+
+    public static final String FIND_BY_NAME = "findByName";
+    public static final String NAME_PARAM = "name";
+
+    /**
+     * The internal object ID used for references to this object. Should be generated by the
+     * underlying storage mechanism
+     */
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "organizationIdGenerator")
+    @TableGenerator(name = "organizationIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "organization", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @OneToOne
+    private JpaAddress address;
+
+    @Basic
+    @Column(name = "description", length = 255)
+    private String description;
+
+    @Basic
+    @Column(name = "endDate")
+    @Temporal(TemporalType.DATE)
+    private Date endDate;
+
+    @Basic
+    @Column(name = "field", length = 255)
+    private String field;
+
+    @Basic
+    @Column(name = "name", length = 255)
+    private String name;
+
+    @Basic
+    @Column(name = "start_date")
+    @Temporal(TemporalType.DATE)
+    private Date startDate;
+
+    @Basic
+    @Column(name = "sub_field", length = 255)
+    private String subField;
+
+    @Basic
+    @Column(name = "title", length = 255)
+    private String title;
+
+    @Basic
+    @Column(name = "webpage", length = 255)
+    private String webpage;
+
+    @Basic
+    @Column(name = "type", length = 255)
+    private String qualifier;
+
+
+    @Basic
+    @Column(name = "primary_organization")
+    private Boolean primary;
+
+    /**
+     */
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public Address getAddress() {
+        return address;
+    }
+
+    @Override
+    public void setAddress(Address address) {
+        this.address = JpaConverter.getInstance().convert(address, Address.class);
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    @Override
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    @Override
+    public String getField() {
+        return field;
+    }
+
+    @Override
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public Date getStartDate() {
+        return startDate;
+    }
+
+    @Override
+    public void setStartDate(Date startDate) {
+        this.startDate = startDate;
+    }
+
+    @Override
+    public String getSubField() {
+        return subField;
+    }
+
+    @Override
+    public void setSubField(String subField) {
+        this.subField = subField;
+    }
+
+    @Override
+    public String getTitle() {
+        return title;
+    }
+
+    @Override
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    @Override
+    public String getWebpage() {
+        return webpage;
+    }
+
+    @Override
+    public void setWebpage(String webpage) {
+        this.webpage = webpage;
+    }
+
+    @Override
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    @Override
+    public void setQualifier(String qualifier) {
+        this.qualifier = qualifier;
+    }
+
+    @Override
+    public Boolean getPrimary() {
+        return primary;
+    }
+
+    @Override
+    public void setPrimary(Boolean primary) {
+        this.primary = primary;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JpaOrganization that = (JpaOrganization) o;
+
+        if (entityId != null ? !entityId.equals(that.entityId) : that.entityId != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return entityId != null ? entityId.hashCode() : 0;
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java
new file mode 100644
index 0000000..6ce3d8d
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPage.java
@@ -0,0 +1,330 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+import org.apache.rave.persistence.BasicEntity;

+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;

+import org.apache.rave.portal.model.conversion.JpaConverter;

+import org.codehaus.jackson.annotate.JsonManagedReference;

+

+import javax.persistence.*;

+import javax.xml.bind.annotation.*;

+import java.io.Serializable;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.List;

+

+/**

+ * A page, which consists of regions, and which may be owned by a {@link JpaUser} (note the ownership will likely need to

+ * become more flexible to enable things like group ownership in the future).

+ *

+ * TODO RAVE-231: not all database providers will be able to support deferrable constraints

+ * so for the time being I'm commenting out the owner/render sequence since it

+ * will get updated in batches and blow up

+ * @UniqueConstraint(columnNames={"owner_id","render_sequence"}

+ *

+ */

+@Entity

+@XmlRootElement

+@XmlAccessorType(XmlAccessType.NONE)

+@Table(name="page", uniqueConstraints={@UniqueConstraint(columnNames={"owner_id","name","page_type"})})

+@NamedQueries({

+        @NamedQuery(name = JpaPage.DELETE_BY_USER_ID_AND_PAGE_TYPE, query="DELETE FROM JpaPage p WHERE p.owner.entityId = :userId and p.pageType = :pageType"),

+        @NamedQuery(name = JpaPage.USER_HAS_PERSON_PAGE, query="SELECT count(p) FROM JpaPage p WHERE p.owner.entityId = :userId and p.pageType = :pageType")

+})

+@Access(AccessType.FIELD)

+public class JpaPage implements BasicEntity, Serializable, Page {

+    private static final long serialVersionUID = 1L;

+

+    public static final String DELETE_BY_USER_ID_AND_PAGE_TYPE = "JpaPage.deleteByUserIdAndPageType";

+    public static final String USER_HAS_PERSON_PAGE = "JpaPage.hasPersonPage";

+

+    @XmlAttribute(name="id")

+    @Id @Column(name="entity_id")

+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageIdGenerator")

+    @TableGenerator(name = "pageIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

+            valueColumnName = "SEQ_COUNT", pkColumnValue = "page", allocationSize = 1, initialValue = 1)

+    private Long entityId;

+

+    @XmlElement

+    @Basic(optional=false) @Column(name="name")

+    private String name;

+

+    @ManyToOne

+    @JoinColumn(name = "owner_id")

+    private JpaUser owner;

+

+    @ManyToOne(cascade=CascadeType.ALL, optional = true)

+    @JoinColumn(name="parent_page_id")

+    private JpaPage parentPage;

+

+    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy="parentPage")

+    private List<JpaPage> subPages;

+

+    @ManyToOne

+    @JoinColumn(name="page_layout_id")

+    private JpaPageLayout pageLayout;

+

+    @XmlElement(name="region")

+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)

+    @OrderBy("renderOrder")

+    @JoinColumn(name="page_id")

+    private List<JpaRegion> regions;

+

+    @Basic

+    @Column(name = "page_type")

+    @Enumerated(EnumType.STRING)

+    private PageType pageType;

+

+    @OneToMany(targetEntity=JpaPageUser.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="page", orphanRemoval=true)

+    private List<JpaPageUser> members;

+

+

+    public JpaPage() {

+    }

+

+    public JpaPage(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    public JpaPage(Long entityId, JpaUser owner) {

+        this.entityId = entityId;

+        this.owner = owner;

+    }

+

+    @Override

+    public Long getId() {

+        return getEntityId();

+    }

+

+    @Override

+    public void setId(Long id) {

+        setEntityId(id);

+    }

+

+    /**

+     * Gets the persistence unique identifier

+     *

+     * @return id The ID of persisted object; null if not persisted

+     */

+    @Override

+    public Long getEntityId() {

+        return entityId;

+    }

+

+    @Override

+    public void setEntityId(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    /**

+     * Gets the user defined name of the page

+     *

+     * @return Valid name

+     */

+    @Override

+    public String getName() {

+        return name;

+    }

+

+    @Override

+    public void setName(String name) {

+        this.name = name;

+    }

+

+    /**

+     * Gets the {@link User} that owns the page

+     *

+     * @return Valid {@link User}

+     */

+    @Override

+    public User getOwner() {

+        return owner;

+    }

+

+    @Override

+    public void setOwner(User owner) {

+        this.owner = JpaConverter.getInstance().convert(owner, User.class);

+    }

+

+    /**

+     * Gets the {@link JpaPageLayout}

+     *

+     * @return Valid {@link JpaPageLayout}

+     */

+    @Override

+    public PageLayout getPageLayout() {

+        return pageLayout;

+    }

+

+    @Override

+    public void setPageLayout(PageLayout pageLayout) {

+        this.pageLayout = JpaConverter.getInstance().convert(pageLayout, PageLayout.class);

+    }

+

+    /**

+     * Gets the widget containing {@link Region}s of the page

+     *

+     * @return Valid list of {@link Region}s

+     */

+    @Override

+    @JsonManagedReference

+    public List<Region> getRegions() {

+        return ConvertingListProxyFactory.createProxyList(Region.class, regions);

+    }

+

+    @Override

+    public void setRegions(List<Region> regions) {

+        if(this.regions == null) {

+            this.regions = new ArrayList<JpaRegion>();

+        }

+        this.getRegions().clear();

+        if(regions != null) {

+            this.getRegions().addAll(regions);

+        }

+    }

+

+    @Override

+    public PageType getPageType() {

+        return pageType;

+    }

+

+    @Override

+    public void setPageType(PageType pageType) {

+        this.pageType = pageType;

+    }

+

+    @Override

+    public Page getParentPage() {

+        return parentPage;

+    }

+

+    @Override

+    public void setParentPage(Page parentPage) {

+        this.parentPage = JpaConverter.getInstance().convert(parentPage, Page.class);

+    }

+

+    @Override

+    public List<Page> getSubPages() {

+        // we need to manually sort the sub pages due to limitations in JPA's OrderBy annotation dealing with

+        // sub-lists

+        List<Page> orderedSubPages = null;

+        if (this.subPages != null) {

+            orderedSubPages = ConvertingListProxyFactory.createProxyList(Page.class, this.subPages);

+            Collections.sort(orderedSubPages, new SubPageComparator());

+        }

+        return orderedSubPages;

+    }

+

+    @Override

+    public void setSubPages(List<Page> subPages) {

+        if(this.subPages == null) {

+            this.subPages = new ArrayList<JpaPage>();

+        }

+        this.getSubPages().clear();

+        if(subPages != null) {

+            this.getSubPages().addAll(subPages);

+        }

+    }

+

+    @Override

+    @JsonManagedReference

+    public List<PageUser> getMembers() {

+        return ConvertingListProxyFactory.createProxyList(PageUser.class, members);

+    }

+

+    @Override

+    public void setMembers(List<PageUser> members) {

+        if (this.members == null) {

+            this.members = new ArrayList<JpaPageUser>();

+        }

+        //Ensure that all operations go through the conversion proxy

+        this.getMembers().clear();

+        if (members != null) {

+            this.getMembers().addAll(members);

+        }

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (obj == null) {

+            return false;

+        }

+        if (getClass() != obj.getClass()) {

+            return false;

+        }

+        final JpaPage other = (JpaPage) obj;

+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {

+            return false;

+        }

+        return true;

+    }

+

+    @Override

+    public int hashCode() {

+        int hash = 7;

+        hash = 89 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);

+        return hash;

+    }

+

+    @Override

+    public String toString() {

+        return "Page{" + "entityId=" + entityId + ", name=" + name + ", owner=" + owner + ", pageLayout=" + pageLayout + ", pageType=" + pageType + "}";

+    }

+

+    /**

+     * Comparator used to sort sub pages.  It looks for PageUser objects representing the sub pages that are owned

+     * by the parent page user, and uses the renderSequence as the sorting field

+     */

+    class SubPageComparator implements Comparator<Page> {

+        @Override

+        public int compare(Page o1, Page o2) {

+            if (o1 == null || o1.getMembers() == null || o1.getMembers().isEmpty()) {

+                return 1;

+            }

+

+            if (o2 == null || o2.getMembers() == null || o2.getMembers().isEmpty()) {

+                return -1;

+            }

+

+            Long o1RenderSequence = null;

+            Long o2RenderSequence = null;

+

+            // find the PageUser object representing the sub page owned by the user

+            for (PageUser pageUser : o1.getMembers()) {

+                if (pageUser.getUser().equals(o1.getOwner())) {

+                    o1RenderSequence = pageUser.getRenderSequence();

+                    break;

+                }

+            }

+

+            // find the PageUser object representing the sub page owned by the user

+            for (PageUser pageUser : o2.getMembers()) {

+                if (pageUser.getUser().equals(o2.getOwner())) {

+                    o2RenderSequence = pageUser.getRenderSequence();

+                    break;

+                }

+            }

+

+            // compare the renderSequences of these two PageUser objects to determine the sort order

+            return o1RenderSequence.compareTo(o2RenderSequence);

+        }

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageLayout.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageLayout.java
new file mode 100644
index 0000000..2e1a7b0
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageLayout.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+/**
+ * Represents an organization of regions within a page that is supported by the rendering engine
+ */
+@Entity
+@Access(AccessType.FIELD)
+@Table(name="page_layout")
+@NamedQueries({
+    @NamedQuery(name= JpaPageLayout.PAGELAYOUT_GET_BY_LAYOUT_CODE, query = "select pl from JpaPageLayout pl where pl.code = :code"),
+    @NamedQuery(name= JpaPageLayout.PAGELAYOUT_GET_ALL, query="select pl from JpaPageLayout pl order by pl.renderSequence"),
+    @NamedQuery(name= JpaPageLayout.PAGELAYOUT_GET_ALL_USER_SELECTABLE, query="select pl from JpaPageLayout pl where pl.userSelectable = true order by pl.renderSequence")
+})
+
+public class JpaPageLayout implements BasicEntity, Serializable, PageLayout {
+    private static final long serialVersionUID = 1L;
+
+    // static string identifiers for JPA queries
+    public static final String PAGELAYOUT_GET_BY_LAYOUT_CODE = "PageLayout.getByLayoutCode";
+    public static final String PAGELAYOUT_GET_ALL = "PageLayout.getAll";
+    public static final String PAGELAYOUT_GET_ALL_USER_SELECTABLE = "PageLayout.getAllUserSelectable";
+    public static final String CODE_PARAM = "code";
+    
+    @Id @Column(name="entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageLayoutIdGenerator")
+    @TableGenerator(name = "pageLayoutIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_layout", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic @Column(name="code", unique = true)
+    private String code;
+
+    @Basic @Column(name="number_of_regions")
+    private Long numberOfRegions;
+
+    @Basic(optional=false) @Column(name="render_sequence")
+    private Long renderSequence;
+
+    @Basic
+    @Column(name = "user_selectable")
+    private boolean userSelectable;
+
+    /**
+     * Gets the persistence unique identifier
+     *
+     * @return id The ID of persisted object; null if not persisted
+     */
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public String getCode() {
+        return code;
+    }
+
+    @Override
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    @Override
+    public Long getNumberOfRegions() {
+        return numberOfRegions;
+    }
+
+    @Override
+    public void setNumberOfRegions(Long numberOfRegions) {
+        this.numberOfRegions = numberOfRegions;
+    }
+
+    @Override
+    public Long getRenderSequence() {
+        return renderSequence;
+    }
+
+    @Override
+    public void setRenderSequence(Long renderSequence) {
+        this.renderSequence = renderSequence;
+    }
+
+    @Override
+    public boolean isUserSelectable() {
+        return userSelectable;
+    }
+
+    @Override
+    public void setUserSelectable(boolean userSelectable) {
+        this.userSelectable = userSelectable;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final JpaPageLayout other = (JpaPageLayout) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "PageLayout{" + "entityId=" + entityId + ", code=" + code + ", numberOfRegions=" + numberOfRegions + '}';
+    }
+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplate.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplate.java
new file mode 100644
index 0000000..b7b20b0
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplate.java
@@ -0,0 +1,203 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+import org.apache.rave.persistence.BasicEntity;

+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;

+import org.apache.rave.portal.model.conversion.JpaConverter;

+

+import javax.persistence.*;

+import java.io.Serializable;

+import java.util.ArrayList;

+import java.util.List;

+

+@Entity

+@Table(name="page_template")

+@NamedQueries({

+        @NamedQuery(name = JpaPageTemplate.PAGE_TEMPLATE_GET_ALL, query = "SELECT p FROM JpaPageTemplate p ORDER BY p.renderSequence"),

+        @NamedQuery(name = JpaPageTemplate.PAGE_TEMPLATE_GET_DEFAULT_PAGE_BY_TYPE, query = "SELECT p FROM JpaPageTemplate p WHERE p.defaultTemplate = true and p.pageType = :pageType")

+})

+@Access(AccessType.FIELD)

+public class JpaPageTemplate implements BasicEntity, Serializable, PageTemplate {

+

+    private static final long serialVersionUID = 1L;

+    public static final String PAGE_TEMPLATE_GET_ALL = "PageTemplate.getAll";

+    public static final String PAGE_TEMPLATE_GET_DEFAULT_PAGE_BY_TYPE = "PageTemplate.getDefaultPage";

+

+    @Id

+    @Column(name="entity_id")

+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageTemplateIdGenerator")

+    @TableGenerator(name = "pageTemplateIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

+            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_template", allocationSize = 1, initialValue = 1)

+    private Long entityId;

+

+    @Basic @Column(name="name", unique = false)

+    private String name;

+    

+    @Basic @Column(name="description", unique = false)

+    private String description;

+

+    @Basic(optional = false)

+    @Column(name="page_type", unique = false)

+    @Enumerated(EnumType.STRING)

+    private PageType pageType;

+

+    @OneToOne(cascade=CascadeType.ALL)

+    @JoinColumn(name="parent_page_template_id")

+    private JpaPageTemplate parentPageTemplate;

+

+    @OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy="parentPageTemplate")

+    @OrderBy("renderSequence")

+    private List<JpaPageTemplate> subPageTemplates;

+

+    @ManyToOne

+    @JoinColumn(name = "page_layout_id")

+    private JpaPageLayout pageLayout;

+

+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)

+    @OrderBy("renderSequence")

+    @JoinColumn(name="page_template_id")

+    private List<JpaPageTemplateRegion> pageTemplateRegions;

+

+    @Basic(optional = false)

+    @Column(name = "render_sequence")

+    private long renderSequence;

+

+    @Basic(optional = false)

+    @Column(name = "default_template")

+    private boolean defaultTemplate;

+

+    @Override

+    public Long getEntityId() {

+        return entityId;

+    }

+

+    @Override

+    public void setEntityId(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    @Override

+    public PageType getPageType() {

+        return pageType;

+    }

+

+    @Override

+    public void setPageType(PageType pageType) {

+        this.pageType = pageType;

+    }

+

+    @Override

+    public String getName() {

+        return name;

+    }

+

+    @Override

+    public void setName(String name) {

+        this.name = name;

+    }

+

+    @Override

+    public String getDescription() {

+        return description;

+    }

+

+    @Override

+    public void setDescription(String description) {

+        this.description = description;

+    }

+

+    @Override

+    public PageTemplate getParentPageTemplate() {

+        return parentPageTemplate;

+    }

+

+    @Override

+    public void setParentPageTemplate(PageTemplate parentPageTemplate) {

+        this.parentPageTemplate = JpaConverter.getInstance().convert(parentPageTemplate, PageTemplate.class);

+    }

+

+    @Override

+    public PageLayout getPageLayout() {

+        return pageLayout;

+    }

+

+    @Override

+    public void setPageLayout(PageLayout pageLayout) {

+        this.pageLayout = JpaConverter.getInstance().convert(pageLayout, PageLayout.class);

+    }

+

+    @Override

+    public List<PageTemplateRegion> getPageTemplateRegions() {

+        return ConvertingListProxyFactory.createProxyList(PageTemplateRegion.class, pageTemplateRegions);

+    }

+

+    @Override

+    public void setPageTemplateRegions(List<PageTemplateRegion> pageTemplateRegions) {

+        if(this.pageTemplateRegions == null) {

+            this.pageTemplateRegions = new ArrayList<JpaPageTemplateRegion>();

+        }

+        this.getPageTemplateRegions().clear();

+        if(pageTemplateRegions != null) {

+            this.getPageTemplateRegions().addAll(pageTemplateRegions);

+        }

+    }

+

+    @Override

+    public long getRenderSequence() {

+        return renderSequence;

+    }

+

+    @Override

+    public void setRenderSequence(long renderSequence) {

+        this.renderSequence = renderSequence;

+    }

+

+    @Override

+    public boolean isDefaultTemplate() {

+        return defaultTemplate;

+    }

+

+    @Override

+    public void setDefaultTemplate(boolean defaultTemplate) {

+        this.defaultTemplate = defaultTemplate;

+    }

+

+    @Override

+    public List<PageTemplate> getSubPageTemplates() {

+        return ConvertingListProxyFactory.createProxyList(PageTemplate.class, subPageTemplates);

+    }

+

+    @Override

+    public void setSubPageTemplates(List<PageTemplate> subPageTemplates) {

+        if(this.subPageTemplates == null) {

+            this.subPageTemplates = new ArrayList<JpaPageTemplate>();

+        }

+        this.getSubPageTemplates().clear();

+        if(subPageTemplates != null) {

+            this.getSubPageTemplates().addAll(subPageTemplates);

+        }

+    }

+

+    @Override

+    public Long getId() {

+        return this.getEntityId();

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplateRegion.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplateRegion.java
new file mode 100644
index 0000000..47bb7c1
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplateRegion.java
@@ -0,0 +1,125 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+import org.apache.rave.persistence.BasicEntity;

+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;

+import org.apache.rave.portal.model.conversion.JpaConverter;

+

+import javax.persistence.*;

+import java.io.Serializable;

+import java.util.ArrayList;

+import java.util.List;

+

+@Entity

+@Table(name = "page_template_region")

+@NamedQueries({

+        @NamedQuery(name = "PageTemplateRegion.findAll", query = "SELECT p FROM JpaPageTemplateRegion p"),

+        @NamedQuery(name = "PageTemplateRegion.findByPageTemplateRegionId", query = "SELECT p FROM JpaPageTemplateRegion p WHERE p.entityId = :id")

+})

+@Access(AccessType.FIELD)

+public class JpaPageTemplateRegion implements BasicEntity, Serializable, PageTemplateRegion {

+    private static final long serialVersionUID = 1L;

+

+    @Id

+    @Column(name="entity_id")

+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageTemplateRegionIdGenerator")

+    @TableGenerator(name = "pageTemplateRegionIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

+            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_template_region", allocationSize = 1, initialValue = 1)

+    private Long entityId;

+

+    @Basic(optional = false)

+    @Column(name = "render_sequence")

+    private long renderSequence;

+

+    @JoinColumn(name = "page_template_id")

+    @ManyToOne(optional = false)

+    private JpaPageTemplate pageTemplate;

+

+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)

+    @OrderBy("renderSequence")

+    @JoinColumn(name = "page_template_region_id")

+    private List<JpaPageTemplateWidget> pageTemplateWidgets;

+    

+    @Basic(optional = false)

+    @Column(name = "locked")

+    private boolean locked;

+

+    @Override

+    public Long getEntityId() {

+        return entityId;

+    }

+

+    @Override

+    public void setEntityId(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    @Override

+    public Long getId() {

+        return this.getEntityId();

+    }

+

+    @Override

+    public long getRenderSequence() {

+        return renderSequence;

+    }

+

+    @Override

+    public void setRenderSequence(long renderSequence) {

+        this.renderSequence = renderSequence;

+    }

+

+    @Override

+    public JpaPageTemplate getPageTemplate() {

+        return pageTemplate;

+    }

+

+    @Override

+    public void setPageTemplate(PageTemplate pageTemplate) {

+        this.pageTemplate = JpaConverter.getInstance().convert(pageTemplate, PageTemplate.class);

+    }

+

+    @Override

+    public List<PageTemplateWidget> getPageTemplateWidgets() {

+        return ConvertingListProxyFactory.createProxyList(PageTemplateWidget.class, this.pageTemplateWidgets);

+    }

+

+    @Override

+    public void setPageTemplateWidgets(List<PageTemplateWidget> pageTemplateWidgets) {

+        if(this.pageTemplateWidgets == null) {

+            this.pageTemplateWidgets = new ArrayList<JpaPageTemplateWidget>();

+        }

+        this.getPageTemplateWidgets().clear();

+        if(pageTemplateWidgets != null) {

+            this.getPageTemplateWidgets().addAll(pageTemplateWidgets);

+        }

+    }

+

+    @Override

+    public boolean isLocked() {

+        return locked;

+    }

+

+    @Override

+    public void setLocked(boolean locked) {

+        this.locked = locked;

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplateWidget.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplateWidget.java
new file mode 100644
index 0000000..03982f0
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageTemplateWidget.java
@@ -0,0 +1,129 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+import org.apache.rave.persistence.BasicEntity;

+import org.apache.rave.portal.model.conversion.JpaConverter;

+

+import javax.persistence.*;

+import java.io.Serializable;

+

+@Entity

+@Table(name= "page_template_widget")

+@NamedQueries({

+        @NamedQuery(name = "PageTemplateGadget.findAll", query = "SELECT p FROM JpaPageTemplateWidget p"),

+        @NamedQuery(name = "PageTemplateGadget.findByPageTemplateGadgetId", query = "SELECT p FROM JpaPageTemplateWidget p WHERE p.entityId = :id")

+})

+@Access(AccessType.FIELD)

+public class JpaPageTemplateWidget implements BasicEntity, Serializable, PageTemplateWidget {

+

+    private static final long serialVersionUID = 1L;

+

+    @Id

+    @Column(name="entity_id")

+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageTemplateWidgetIdGenerator")

+    @TableGenerator(name = "pageTemplateWidgetIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

+            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_template_widget", allocationSize = 1, initialValue = 1)

+    private Long entityId;

+

+    @JoinColumn(name = "page_template_region_id")

+    @ManyToOne(optional = false)

+    private JpaPageTemplateRegion pageTemplateRegion;

+

+    @Basic(optional = false)

+    @Column(name = "render_sequence")

+    private long renderSequence;

+

+    @JoinColumn(name = "widget_id")

+    @ManyToOne(optional = false)

+    private JpaWidget widget;

+

+    @Basic(optional = false)

+    @Column(name = "locked")

+    private boolean locked;

+

+    @Basic(optional = false)

+    @Column(name = "hide_chrome")

+    private boolean hideChrome;

+

+    @Override

+    public Long getEntityId() {

+        return entityId;

+    }

+

+    @Override

+    public void setEntityId(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    @Override

+    public Long getId() {

+        return this.getEntityId();

+    }

+

+    @Override

+    public PageTemplateRegion getPageTemplateRegion() {

+        return pageTemplateRegion;

+    }

+

+    @Override

+    public void setPageTemplateRegion(PageTemplateRegion pageTemplateRegion) {

+        this.pageTemplateRegion = JpaConverter.getInstance().convert(pageTemplateRegion, PageTemplateRegion.class);

+    }

+

+    @Override

+    public long getRenderSeq() {

+        return renderSequence;

+    }

+

+    @Override

+    public void setRenderSeq(long renderSeq) {

+        this.renderSequence = renderSeq;

+    }

+

+    @Override

+    public JpaWidget getWidget() {

+        return widget;

+    }

+

+    @Override

+    public void setWidget(Widget widget) {

+        this.widget = JpaConverter.getInstance().convert(widget, Widget.class);

+    }

+

+    @Override

+    public boolean isLocked() {

+        return locked;

+    }

+

+    @Override

+    public void setLocked(boolean locked) {

+        this.locked = locked;

+    }

+

+    @Override

+    public boolean isHideChrome() {

+        return hideChrome;

+    }

+

+    @Override

+    public void setHideChrome(boolean hideChrome) {

+        this.hideChrome = hideChrome;

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageUser.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageUser.java
new file mode 100644
index 0000000..f46a1b1
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPageUser.java
@@ -0,0 +1,179 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+import java.io.Serializable;

+

+import javax.persistence.*;

+

+import org.apache.rave.persistence.BasicEntity;

+import org.apache.rave.portal.model.conversion.JpaConverter;

+import org.codehaus.jackson.annotate.JsonBackReference;

+@Entity

+@Access(AccessType.FIELD)

+@Table(name = "page_user", uniqueConstraints={@UniqueConstraint(columnNames={"page_id","user_id"})})

+@NamedQueries({

+        @NamedQuery(name = JpaPageUser.GET_BY_USER_ID_AND_PAGE_TYPE, query="SELECT p.page FROM JpaPageUser p, JpaPage q WHERE p.page.entityId = q.entityId and p.user.entityId = :userId and q.pageType = :pageType ORDER BY p.renderSequence"),

+        @NamedQuery(name = JpaPageUser.GET_PAGES_FOR_USER, query="SELECT p FROM JpaPageUser p, JpaPage q WHERE p.page.entityId = q.entityId and p.user.entityId = :userId and q.pageType = :pageType ORDER BY p.renderSequence"),

+        @NamedQuery(name = JpaPageUser.GET_SINGLE_RECORD, query="SELECT p FROM JpaPageUser p WHERE p.user.entityId = :userId and p.page.entityId = :pageId")

+})

+public class JpaPageUser implements BasicEntity, Serializable, PageUser {

+    private static final long serialVersionUID = 1L;

+

+    public static final String GET_BY_USER_ID_AND_PAGE_TYPE ="JpaPageUser.getByUserIdAndPageType";

+    public static final String GET_PAGES_FOR_USER = "JpaPageUser.getPagesForUser";

+    public static final String GET_SINGLE_RECORD = "JpaPageUser.getSingleRecord";

+

+    @Id @Column(name="entity_id")

+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pageUserIdGenerator")

+    @TableGenerator(name = "pageUserIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

+            valueColumnName = "SEQ_COUNT", pkColumnValue = "page_user", allocationSize = 1, initialValue = 1)

+

+    private Long entityId;

+

+    @ManyToOne

+    @JoinColumn(name = "user_id")

+    private JpaUser user;

+

+    @ManyToOne(fetch=FetchType.EAGER)

+    @JoinColumn(name = "page_id")

+    private JpaPage page;

+

+    @Basic(optional=false) @Column(name="editor")

+    private boolean editor;

+

+    @Basic(optional=false) @Column(name="render_sequence")

+    private Long renderSequence;

+

+    @Basic

+    @Column(name = "page_status")

+    @Enumerated(EnumType.STRING)

+    private PageInvitationStatus pageStatus;

+

+    public JpaPageUser(){}

+

+    public JpaPageUser(User user, Page page){

+        this.setUser(user);

+        setPage(page);

+    }

+

+    public JpaPageUser(JpaUser user, Page page, long sequence){

+        this.user = user;

+        setPage(page);

+        this.renderSequence = sequence;

+    }

+

+    public Long getEntityId() {

+        return entityId;

+    }

+

+    public void setEntityId(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    @Override

+    public Long getId() {

+        return getEntityId();

+    }

+

+    @Override

+    public void setId(Long id) {

+        setEntityId(id);

+    }

+

+    /**

+	 * @return the editor

+	 */

+	@Override

+    public boolean isEditor() {

+        return editor;

+	}

+

+    /**

+    * @param editor the editor to set

+    */

+    @Override

+    public void setEditor(boolean editor) {

+        this.editor = editor;

+    }

+

+    /**

+    * @return the user

+    */

+    @Override

+    public JpaUser getUser() {

+        return user;

+    }

+

+    /**

+    * @param user the user to set

+    */

+    @Override

+    public void setUser(User user) {

+        this.user = JpaConverter.getInstance().convert(user, User.class);

+    }

+

+    /**

+    * @return the page

+    */

+    @Override

+    @JsonBackReference

+    public Page getPage() {

+        return page;

+    }

+

+    /**

+    * @param page the page to set

+    */

+    @Override

+    public void setPage(Page page) {

+        this.page = JpaConverter.getInstance().convert(page, Page.class);

+    }

+

+    /**

+     * Gets the order of the page instance relative to all pages for the owner (useful when presenting pages in an

+     * ordered layout like tabs or an accordion container)

+     *

+     * @return Valid, unique render sequence

+     */

+    @Override

+    public Long getRenderSequence() {

+        return renderSequence;

+    }

+

+    @Override

+    public void setRenderSequence(Long renderSequence) {

+        this.renderSequence = renderSequence;

+    }

+

+    /**

+     * Get the page status - used in shared states where a page can be pending, refused or accepted

+     * Only applies to shared pages

+     * @return an enum type

+     */

+    @Override

+    public PageInvitationStatus getPageStatus() {

+        return pageStatus;

+    }

+

+    @Override

+    public void setPageStatus(PageInvitationStatus pageStatus) {

+        this.pageStatus = pageStatus;

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPerson.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPerson.java
new file mode 100644
index 0000000..d286e82
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPerson.java
@@ -0,0 +1,338 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a person in the persistence context
+ */
+@Entity
+@Table(name = "person")
+@Access(AccessType.FIELD)
+@NamedQueries(value = {
+    @NamedQuery(name = JpaPerson.FIND_BY_USERNAME, query = "select p from JpaPerson p where p.username like :username"),
+    @NamedQuery(name = JpaPerson.FIND_FRIENDS_BY_USERNAME, query = "select a.followed from JpaPersonAssociation a where a.follower.username = :username"),
+    @NamedQuery(name = JpaPerson.FIND_BY_GROUP_MEMBERSHIP, query = "select m from JpaGroup g join g.members m where exists " +
+            "(select 'found' from g.members b where b.username = :username) and m.username <> :username")
+})
+@DiscriminatorValue("Person")
+public class JpaPerson implements BasicEntity, Person {
+
+    public static final String FIND_BY_USERNAME = "Person.findByUsername";
+    public static final String FIND_FRIENDS_BY_USERNAME = "Person.findFriendsByUsername";
+    public static final String FIND_BY_GROUP_MEMBERSHIP = "Person.findByGroupMembership";
+    public static final String USERNAME_PARAM = "username";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "personIdGenerator")
+    @TableGenerator(name = "personIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "person", allocationSize = 1, initialValue = 1)
+    protected Long entityId;
+
+    @Basic
+    @Column(name = "username", unique = true)
+    protected String username;
+
+    @Basic
+    @Column(name = "email", unique = true)
+    protected String email;
+
+    @Basic
+    @Column(name = "display_name", length = 255)
+    protected String displayName;
+
+    @Basic
+    @Column(name = "additional_name", length = 255)
+    protected String additionalName;
+
+    @Basic
+    @Column(name = "family_name", length = 255)
+    protected String familyName;
+
+    @Basic
+    @Column(name = "given_name", length = 255)
+    protected String givenName;
+
+    @Basic
+    @Column(name = "honorific_prefix", length = 255)
+    protected String honorificPrefix;
+
+    @Basic
+    @Column(name = "honorific_suffix", length = 255)
+    protected String honorificSuffix;
+
+    @Basic
+    @Column(name = "preferred_name")
+    protected String preferredName;
+
+    @Basic
+    @Column(name = "about_me")
+    protected String aboutMe;
+
+    @Basic
+    @Column(name = "status")
+    protected String status;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinTable(name = "person_address_jn",
+            joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "entity_id"),
+            inverseJoinColumns = @JoinColumn(name="person_id", referencedColumnName = "entity_id"))
+    protected List<JpaAddress> addresses;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinColumn(name="person_id", referencedColumnName = "entity_id")
+    protected List<JpaOrganization> organizations;
+
+    @OneToMany(targetEntity = JpaPersonProperty.class)
+    @JoinColumn(name = "person_id", referencedColumnName = "entity_id")
+    protected List<JpaPersonProperty> properties;
+
+    @ManyToMany(fetch = FetchType.LAZY)
+    @JoinTable(name = "person_association",
+            joinColumns = @JoinColumn(name = "follower_id", referencedColumnName = "entity_id"),
+            inverseJoinColumns = @JoinColumn(name = "followed_id", referencedColumnName = "entity_id"))
+    protected List<JpaPerson> friends;
+
+    @ManyToMany(fetch = FetchType.LAZY)
+    @JoinTable(name = "group_members",
+            joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "entity_id"),
+            inverseJoinColumns = @JoinColumn(name = "group_id", referencedColumnName = "entity_id"))
+    private List<JpaGroup> groups;
+
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    @Override
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    @Override
+    public String getEmail() {
+        return email;
+    }
+
+    @Override
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    @Override
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    @Override
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    @Override
+    public String getAboutMe() {
+        return aboutMe;
+    }
+
+    @Override
+    public void setAboutMe(String aboutMe) {
+        this.aboutMe = aboutMe;
+    }
+
+    @Override
+    public String getPreferredName() {
+        return preferredName;
+    }
+
+    @Override
+    public void setPreferredName(String preferredName) {
+        this.preferredName = preferredName;
+    }
+
+    @Override
+    public String getStatus() {
+        return status;
+    }
+
+    @Override
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    @Override
+    public String getAdditionalName() {
+        return additionalName;
+    }
+
+    @Override
+    public void setAdditionalName(String additionalName) {
+        this.additionalName = additionalName;
+    }
+
+    @Override
+    public String getFamilyName() {
+        return familyName;
+    }
+
+    @Override
+    public void setFamilyName(String familyName) {
+        this.familyName = familyName;
+    }
+
+    @Override
+    public String getGivenName() {
+        return givenName;
+    }
+
+    @Override
+    public void setGivenName(String givenName) {
+        this.givenName = givenName;
+    }
+
+    @Override
+    public String getHonorificPrefix() {
+        return honorificPrefix;
+    }
+
+    @Override
+    public void setHonorificPrefix(String honorificPrefix) {
+        this.honorificPrefix = honorificPrefix;
+    }
+
+    @Override
+    public String getHonorificSuffix() {
+        return honorificSuffix;
+    }
+
+    @Override
+    public void setHonorificSuffix(String honorificSuffix) {
+        this.honorificSuffix = honorificSuffix;
+    }
+
+    @Override
+    public List<Address> getAddresses() {
+        return ConvertingListProxyFactory.createProxyList(Address.class, addresses);
+    }
+
+    @Override
+    public void setAddresses(List<Address> addresses) {
+        if(this.addresses == null) {
+            this.addresses = new ArrayList<JpaAddress>();
+        }
+        this.getAddresses().clear();
+        if(addresses != null) {
+            this.getAddresses().addAll(addresses);
+        }
+    }
+
+    @Override
+    public List<PersonProperty> getProperties() {
+        return ConvertingListProxyFactory.createProxyList(PersonProperty.class, this.properties);
+    }
+
+    @Override
+    public void setProperties(List<PersonProperty> properties) {
+        if(this.properties == null) {
+            this.properties = new ArrayList<JpaPersonProperty>();
+        }
+        this.getProperties().clear();
+        if(properties != null) {
+            this.getProperties().addAll(properties);
+        }
+    }
+
+    @Override
+    public List<Person> getFriends() {
+        return ConvertingListProxyFactory.createProxyList(Person.class, friends);
+    }
+
+    @Override
+    public void setFriends(List<Person> friends) {
+        if(this.friends == null) {
+            this.friends = new ArrayList<JpaPerson>();
+        }
+        //Ensure that all operations go through the conversion proxy
+        this.getFriends().clear();
+        if(friends != null) {
+            this.getFriends().addAll(friends);
+        }
+    }
+
+    @Override
+    public List<Organization> getOrganizations() {
+        return ConvertingListProxyFactory.createProxyList(Organization.class, organizations);
+    }
+
+    @Override
+    public void setOrganizations(List<Organization> organizations) {
+        if(this.organizations == null) {
+            this.organizations = new ArrayList<JpaOrganization>();
+        }
+        this.getOrganizations().clear();
+        if(organizations != null) {
+            this.getOrganizations().addAll(organizations);
+        }
+    }
+
+    public List<Group> getGroups() {
+        return ConvertingListProxyFactory.createProxyList(Group.class, groups);
+    }
+
+    public void setGroups(List<JpaGroup> groups) {
+        if(this.groups == null) {
+            this.groups = new ArrayList<JpaGroup>();
+        }
+        this.getGroups().clear();
+        if(groups != null) {
+            this.getGroups().addAll(groups);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        JpaPerson person = (JpaPerson) o;
+
+        if (entityId != null ? !entityId.equals(person.entityId) : person.entityId != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return entityId != null ? entityId.hashCode() : 0;
+    }
+}
+
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonAssociation.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPersonAssociation.java
similarity index 87%
rename from rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonAssociation.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPersonAssociation.java
index d4c4d26..8ea1f26 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/model/PersonAssociation.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPersonAssociation.java
@@ -26,10 +26,11 @@
  * Represents an association between people
  */
 @Entity
+@Access(AccessType.FIELD)
 @Table(name = "person_association",
         uniqueConstraints = @UniqueConstraint(columnNames = {"follower_id", "followed_id"})
 )
-public class PersonAssociation implements BasicEntity {
+public class JpaPersonAssociation implements BasicEntity {
 
     @Id
     @Column(name = "entity_id")
@@ -40,11 +41,11 @@
 
     @OneToOne
     @JoinColumn(name="follower_id", referencedColumnName = "entity_id")
-    Person follower;
+    JpaPerson follower;
 
     @OneToOne
     @JoinColumn(name="followed_id", referencedColumnName = "entity_id")
-    Person followed;
+    JpaPerson followed;
 
     @Override
     public Long getEntityId() {
@@ -60,15 +61,15 @@
         return follower;
     }
 
-    public void setFollower(Person follower) {
+    public void setFollower(JpaPerson follower) {
         this.follower = follower;
     }
 
-    public Person getFollowed() {
+    public JpaPerson getFollowed() {
         return followed;
     }
 
-    public void setFollowed(Person followed) {
+    public void setFollowed(JpaPerson followed) {
         this.followed = followed;
     }
 
@@ -77,7 +78,7 @@
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
 
-        PersonAssociation that = (PersonAssociation) o;
+        JpaPersonAssociation that = (JpaPersonAssociation) o;
 
         if (entityId != null ? !entityId.equals(that.entityId) : that.entityId != null) return false;
 
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPersonProperty.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPersonProperty.java
new file mode 100644
index 0000000..896359a
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPersonProperty.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+
+import javax.persistence.*;
+
+/**
+ * A generic extension model for the {@link JpaPerson} that allows implementers to
+ * add fields to the Person not initially envisioned
+ */
+@Entity
+@Access(AccessType.FIELD)
+@Table(name = "person_property")
+public class JpaPersonProperty implements BasicEntity, PersonProperty {
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "personPropertyIdGenerator")
+    @TableGenerator(name = "personPropertyIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "person_property", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    /**
+     * The property type (IM, PhoneNumber, etc)
+     */
+    @Basic
+    @Column(name = "type")
+    private String type;
+
+    /**
+     * The value of the field
+     */
+    @Basic
+    @Column(name = "value")
+    private String value;
+
+    /**
+     * The distinguishing qualifier (Home, Work, etc)
+     */
+    @Basic
+    @Column(name = "qualifier")
+    private String qualifier;
+
+    /**
+     * Extended information related to the value
+     */
+    @Basic
+    @Column(name = "extended_value")
+    private String extendedValue;
+
+    /**
+     * Determines whether or not the property is the designated primary for the type
+     */
+    @Basic
+    @Column(name = "primary_value")
+    private Boolean primary;
+
+    public JpaPersonProperty() {
+    }
+
+    public JpaPersonProperty(Long entityId, String type, String value, String extendedValue, String qualifier, Boolean primary) {
+        this.entityId = entityId;
+        this.type = type;
+        this.value = value;
+        this.qualifier = qualifier;
+        this.primary = primary;
+        this.extendedValue = extendedValue;
+    }
+
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public Long getId() {
+        return this.getEntityId();
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.setEntityId(id);
+    }
+
+    @Override
+    public String getType() {
+        return type;
+    }
+
+    @Override
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    @Override
+    public void setQualifier(String qualifier) {
+        this.qualifier = qualifier;
+    }
+
+    @Override
+    public Boolean getPrimary() {
+        return primary;
+    }
+
+    @Override
+    public void setPrimary(Boolean primary) {
+        this.primary = primary;
+    }
+
+    @Override
+    public String getExtendedValue() {
+        return extendedValue;
+    }
+
+    @Override
+    public void setExtendedValue(String extendedValue) {
+        this.extendedValue = extendedValue;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JpaPersonProperty that = (JpaPersonProperty) o;
+
+        if (entityId != null ? !entityId.equals(that.entityId) : that.entityId != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return entityId != null ? entityId.hashCode() : 0;
+    }
+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPortalPreference.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPortalPreference.java
new file mode 100644
index 0000000..853a5ca
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaPortalPreference.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.exception.NotSupportedException;
+import org.apache.rave.persistence.BasicEntity;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Bean to manage portal preferences like title suffix, logo, number of items per page etc
+ */
+@Entity
+@Access(AccessType.FIELD)
+@Table(name = "portal_preference")
+@NamedQueries({
+        @NamedQuery(name = JpaPortalPreference.GET_ALL, query = "SELECT pp FROM JpaPortalPreference pp"),
+        @NamedQuery(name = JpaPortalPreference.GET_BY_KEY,
+                query = "SELECT pp FROM JpaPortalPreference pp WHERE pp.key = :" + JpaPortalPreference.PARAM_KEY)
+})
+public class JpaPortalPreference implements BasicEntity, Serializable, PortalPreference {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final String GET_ALL = "PortalPreference.getAll";
+    public static final String GET_BY_KEY = "PortalPreference.getByKey";
+    public static final String PARAM_KEY = "key";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "portalPreferenceIdGenerator")
+    @TableGenerator(name = "portalPreferenceIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "portal_preference", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic
+    @Column(name = "preference_key", unique = true)
+    private String key;
+
+    @ElementCollection(fetch = FetchType.EAGER)
+    private List<String> values = new LinkedList<String>();
+
+    public JpaPortalPreference() {
+        super();
+    }
+
+    public JpaPortalPreference(String key, String value) {
+        super();
+        this.key = key;
+        this.values.add(value);
+    }
+
+    public JpaPortalPreference(String key, List<String> values) {
+        super();
+        this.key = key;
+        this.values = values;
+    }
+
+    @Override
+    public Long getEntityId() {
+        return this.entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @Override
+    public void setKey(String key) {
+        this.key = key;
+    }
+
+    @Override
+    public List<String> getValues() {
+        return values;
+    }
+
+    @Override
+    public void setValues(List<String> values) {
+        this.values = values;
+    }
+
+    @Override
+    public String getValue() {
+        if (values.isEmpty()) {
+            return null;
+        } else if (values.size() == 1) {
+            return values.get(0);
+        }
+        throw new NotSupportedException("Cannot return single value for a List of size " + values.size());
+    }
+
+    @Override
+    public void setValue(String value) {
+        List<String> values = new ArrayList<String>();
+        values.add(value);
+        this.values = values;
+    }
+
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final JpaPortalPreference other = (JpaPortalPreference) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("PortalPreference");
+        sb.append("{entityId=").append(entityId);
+        sb.append(", key='").append(key).append('\'');
+        sb.append(", values={");
+        if (values != null) {
+            for (int i = 0; i < values.size(); i++) {
+                if (i > 0) {
+                    sb.append(',');
+                }
+                sb.append('\'').append(values.get(i)).append('\'');
+            }
+            sb.append('}');
+        }
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegion.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegion.java
new file mode 100644
index 0000000..67f2fce
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegion.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+import org.apache.rave.portal.model.conversion.JpaConverter;
+import org.codehaus.jackson.annotate.JsonBackReference;
+import org.codehaus.jackson.annotate.JsonManagedReference;
+
+import javax.persistence.*;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A region of a page, which can contain widget instances {@link RegionWidget}
+ */
+@XmlAccessorType(XmlAccessType.NONE)
+@Entity
+@Table(name="region")
+@Access(AccessType.FIELD)
+@NamedQueries(
+        @NamedQuery(name = JpaRegion.FIND_BY_ENTITY_ID, query="select r from JpaRegion r where r.entityId = :entity_id")
+)
+public class JpaRegion implements BasicEntity, Serializable, Region {
+    private static final long serialVersionUID = 1L;
+
+    public static final String FIND_BY_ENTITY_ID = "Region.findByEntityId";
+    public static final String ENTITY_ID_PARAM = "entity_id";
+
+    @Id @Column(name="entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "regionIdGenerator")
+    @TableGenerator(name = "regionIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "region", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @ManyToOne
+    @JoinColumn(name = "page_id")
+    private JpaPage page;
+
+    @Basic
+    @Column(name = "render_order")
+    private int renderOrder;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+    @OrderBy("renderOrder")
+    @JoinColumn(name = "region_id")
+    private List<JpaRegionWidget> regionWidgets;
+
+    @Basic(optional = false)
+    @Column(name = "locked")
+    private boolean locked;
+
+    public JpaRegion() {
+    }
+
+    public JpaRegion(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    public JpaRegion(Long entityId, JpaPage page, int renderOrder) {
+        this.entityId = entityId;
+        this.page = page;
+        this.renderOrder = renderOrder;
+    }
+
+    @SuppressWarnings("unused")
+    @XmlElement(name="widget")
+    /**
+     * Only used for XML serialization, omitting regionwidget
+     */
+    private List<Widget> getWidgets(){
+        ArrayList<Widget> widgets = new ArrayList<Widget>();
+        for (RegionWidget rw: regionWidgets){
+            widgets.add(rw.getWidget());
+        }
+        return widgets;
+    }
+
+    /**
+     * Gets the persistence unique identifier
+     *
+     * @return id The ID of persisted object; null if not persisted
+     */
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public Long getId() {
+        return getEntityId();
+    }
+
+    @Override
+    public void setId(Long id) {
+        setEntityId(id);
+    }
+
+    /**
+     * Gets the associated page
+     *
+     * @return the associated page
+     */
+    @Override
+    @JsonBackReference
+    public Page getPage() {
+        return page;
+    }
+
+    @Override
+    public void setPage(Page page) {
+        this.page = JpaConverter.getInstance().convert(page, Page.class);
+    }
+
+    /**
+     * Gets the order relative to regions on the page
+     *
+     * @return the order of the region
+     */
+    @Override
+    public int getRenderOrder() {
+        return renderOrder;
+    }
+
+    @Override
+    public void setRenderOrder(int renderOrder) {
+        this.renderOrder = renderOrder;
+    }
+
+    /**
+     * Gets the ordered list of widget instances for the region
+     *
+     * @return Valid list
+     */
+    @Override
+    @JsonManagedReference
+    public List<RegionWidget> getRegionWidgets() {
+        return ConvertingListProxyFactory.createProxyList(RegionWidget.class, regionWidgets);
+    }
+
+    @Override
+    public void setRegionWidgets(List<RegionWidget> regionWidgets) {
+        if(this.regionWidgets == null) {
+            this.regionWidgets = new ArrayList<JpaRegionWidget>();
+        }
+        this.getRegionWidgets().clear();
+        if(regionWidgets != null) {
+            this.getRegionWidgets().addAll(regionWidgets);
+        }
+    }
+
+    @Override
+    public boolean isLocked() {
+        return locked;
+    }
+
+    @Override
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final JpaRegion other = (JpaRegion) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 67 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "JpaRegion{" + "entityId=" + entityId + ", pageId=" + ((page == null) ? null : page.getEntityId()) + ", regionWidgets=" + regionWidgets + '}';
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegionWidget.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegionWidget.java
new file mode 100644
index 0000000..e842954
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegionWidget.java
@@ -0,0 +1,294 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+import org.apache.rave.portal.model.conversion.JpaConverter;
+import org.codehaus.jackson.annotate.JsonBackReference;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A widget within a region
+ */
+@Entity
+@Access(AccessType.FIELD)
+@Table(name = "region_widget")
+@NamedQueries({
+        @NamedQuery(name = JpaRegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_ALL_WIDGETS,
+                    query = "select rw.widget.entityId, count(distinct rw.region.page.owner) from JpaRegionWidget rw group by rw.widget.entityId"),
+        @NamedQuery(name = JpaRegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_SINGLE_WIDGET,
+                    query = "select count(distinct rw.region.page.owner) from JpaRegionWidget rw where rw.widget.entityId = :widgetId"),
+        @NamedQuery(name = JpaRegionWidget.FIND_BY_ID,
+                    query = "select rw from JpaRegionWidget rw where rw.entityId = :widgetId")
+})
+public class JpaRegionWidget implements BasicEntity, Serializable, RegionWidget {
+    private static final long serialVersionUID = 1L;
+
+    public static final String FIND_BY_ID = "RegionWidget.findById";
+    public static final String REGION_WIDGET_GET_DISTINCT_USER_COUNT_ALL_WIDGETS = "JpaRegionWidget.getDistinctUserCountForAllWidgets";
+    public static final String REGION_WIDGET_GET_DISTINCT_USER_COUNT_SINGLE_WIDGET = "JpaRegionWidget.getDistinctUserCount";
+
+    public static final String PARAM_WIDGET_ID = "widgetId";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "regionWidgetIdGenerator")
+    @TableGenerator(name = "regionWidgetIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "region_widget", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @ManyToOne
+    @JoinColumn(name = "widget_id")
+    private JpaWidget widget;
+
+    @ManyToOne
+    @JoinColumn(name = "region_id")
+    private JpaRegion region;
+
+    @Basic
+    @Column(name = "render_position")
+    private String renderPosition;
+
+    @Basic
+    @Column(name = "render_order")
+    private int renderOrder;
+
+    @Basic
+    @Column(name = "collapsed")
+    private boolean collapsed;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinColumn(name = "region_widget_id", referencedColumnName = "entity_id")
+    private List<JpaRegionWidgetPreference> preferences;
+
+    @Basic(optional = false)
+    @Column(name = "locked")
+    private boolean locked;
+
+    @Basic(optional = false)
+    @Column(name = "hide_chrome")
+    private boolean hideChrome;
+
+    public JpaRegionWidget() {
+    }
+
+    public JpaRegionWidget(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    public JpaRegionWidget(Long entityId, JpaWidget widget, JpaRegion region, int renderOrder) {
+        this.entityId = entityId;
+        this.widget = widget;
+        this.region = region;
+        this.renderOrder = renderOrder;
+    }
+
+    public JpaRegionWidget(Long entityId, JpaWidget widget, JpaRegion region) {
+        this.entityId = entityId;
+        this.widget = widget;
+        this.region = region;
+    }
+
+    /**
+     * Gets the persistence unique identifier
+     *
+     * @return id The ID of persisted object; null if not persisted
+     */
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public Long getId() {
+        return getEntityId();
+    }
+
+    @Override
+    public void setId(Long id) {
+        setEntityId(id);
+    }
+
+    /**
+     * Gets the object that represents the metadata about the widget
+     *
+     * @return valid widget
+     */
+    @Override
+    public Widget getWidget() {
+        return widget;
+    }
+
+    @Override
+    public void setWidget(Widget widget) {
+        this.widget = JpaConverter.getInstance().convert(widget, Widget.class);;
+    }
+
+    /**
+     * Gets the associated region
+     *
+     * @return the region
+     */
+    @Override
+    @JsonBackReference
+    public Region getRegion() {
+        return region;
+    }
+
+    @Override
+    public void setRegion(Region region) {
+        this.region = JpaConverter.getInstance().convert(region, Region.class);
+    }
+
+    /**
+     * Gets the render position of this widget.  When the widget instance is being displayed on a "desktop" type view
+     * (single region where the user can drag and drop widgets to a particular X and Y coordinate within that region)
+     * this value might be an X and Y coordinate of the upper left hand corner of the widget.  It will be up to the
+     * rendering engine (based on the type of PageLayout associated with the Page this widget is rendering on) to
+     * determine how to use the value from this field.
+     *
+     * @return The RegionWidgets position within the Region
+     */
+    @Override
+    public String getRenderPosition() {
+        return renderPosition;
+    }
+
+    @Override
+    public void setRenderPosition(String renderPosition) {
+        this.renderPosition = renderPosition;
+    }
+
+    /**
+     * Gets the order relative to other gadgets in the region
+     *
+     * @return the order of the gadget
+     */
+    @Override
+    public int getRenderOrder() {
+        return renderOrder;
+    }
+
+    @Override
+    public void setRenderOrder(int renderOrder) {
+        this.renderOrder = renderOrder;
+    }
+
+    /**
+     * Gets whether or not to render the gadget in collapsed mode
+     *
+     * @return true if render collapsed; false otherwise
+     */
+    @Override
+    public boolean isCollapsed() {
+        return collapsed;
+    }
+
+    @Override
+    public void setCollapsed(boolean collapsed) {
+        this.collapsed = collapsed;
+    }
+
+    /**
+     * Gets the collection of user defined preferences for this RegionWidget.
+     *
+     * @return The user defined preferences for this RegionWidget.
+     */
+    @Override
+    public List<RegionWidgetPreference> getPreferences() {
+        return ConvertingListProxyFactory.createProxyList(RegionWidgetPreference.class, preferences);
+    }
+
+    @Override
+    public void setPreferences(List<RegionWidgetPreference> preferences) {
+        if(this.preferences == null) {
+            this.preferences = new ArrayList<JpaRegionWidgetPreference>();
+        }
+        this.getPreferences().clear();
+        if(preferences != null) {
+            this.getPreferences().addAll(preferences);
+        }
+    }
+
+    @Override
+    public boolean isLocked() {
+        return locked;
+    }
+
+    @Override
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    @Override
+    public boolean isHideChrome() {
+        return hideChrome;
+    }
+
+    @Override
+    public void setHideChrome(boolean hideChrome) {
+        this.hideChrome = hideChrome;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final JpaRegionWidget other = (JpaRegionWidget) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 23 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("JpaRegionWidget{");
+        sb.append("entityId=");
+        sb.append(entityId);
+        sb.append(",widget=");
+        sb.append(widget);
+        sb.append(",regionId=");
+        sb.append(region.getEntityId());
+        sb.append("}");
+        return sb.toString();
+    }
+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegionWidgetPreference.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegionWidgetPreference.java
new file mode 100644
index 0000000..b5c6346
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaRegionWidgetPreference.java
@@ -0,0 +1,150 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model;

+

+import org.apache.rave.persistence.BasicEntity;

+

+import javax.persistence.*;

+import javax.xml.bind.annotation.XmlRootElement;

+import java.io.Serializable;

+

+/**

+ * A preference for a region widget.

+ */

+@Entity

+@Access(AccessType.FIELD)

+@Table(name = "region_widget_preference")

+@NamedQueries(value = {

+        @NamedQuery(name = JpaRegionWidgetPreference.FIND_BY_REGION_WIDGET_AND_NAME, query = "select p from JpaRegionWidgetPreference p where p.regionWidgetId = :widgetId and p.name = :name")

+})

+@XmlRootElement

+public class JpaRegionWidgetPreference implements BasicEntity, Serializable, RegionWidgetPreference {

+

+    public static final String FIND_BY_REGION_WIDGET_AND_NAME = "JpaRegionWidgetPreference.findByRegionWidgetAndName";

+    public static final String NAME_PARAM = "name";

+    public static final String REGION_WIDGET_ID = "widgetId";

+

+    private static final long serialVersionUID = 1L;

+    

+    @Id

+    @Column(name = "entity_id")

+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "regionWidgetPreferenceIdGenerator")

+    @TableGenerator(name = "regionWidgetPreferenceIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",

+            valueColumnName = "SEQ_COUNT", pkColumnValue = "region_widget_preference", allocationSize = 1, initialValue = 1)

+    private Long entityId;

+

+    @Basic

+    @Column(name = "region_widget_id")

+    private Long regionWidgetId;

+

+    @Basic

+    @Column(name = "name")

+    private String name;

+

+    @Basic

+    @Column(name = "value")

+    private String value;

+

+    public JpaRegionWidgetPreference() {

+    }

+

+    public JpaRegionWidgetPreference(Long entityId, Long regionWidgetId, String name, String value) {

+        this.entityId = entityId;

+        this.regionWidgetId = regionWidgetId;

+        this.name = name;

+        this.value = value;

+    }

+

+    /**

+     * Gets the persistence unique identifier

+     *

+     * @return id The ID of persisted object; null if not persisted

+     */

+    @Override

+    public Long getEntityId() {

+        return entityId;

+    }

+

+    @Override

+    public void setEntityId(Long entityId) {

+        this.entityId = entityId;

+    }

+

+    @Override

+    public Long getRegionWidgetId() {

+        return regionWidgetId;

+    }

+

+    @Override

+    public void setRegionWidgetId(Long regionWidgetId) {

+        this.regionWidgetId = regionWidgetId;

+    }

+

+    @Override

+    public String getName() {

+        return name;

+    }

+

+    @Override

+    public void setName(String name) {

+        this.name = name;

+    }

+

+    @Override

+    public String getValue() {

+        return value;

+    }

+

+    @Override

+    public void setValue(String value) {

+        this.value = value;

+    }

+

+    @Override

+    public boolean equals(Object obj) {

+        if (obj == null) {

+            return false;

+        }

+        if (getClass() != obj.getClass()) {

+            return false;

+        }

+        final JpaRegionWidgetPreference other = (JpaRegionWidgetPreference) obj;

+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {

+            return false;

+        }

+        return true;

+    }

+

+    @Override

+    public int hashCode() {

+        int hash = 7;

+        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);

+        return hash;

+    }

+

+    @Override

+    public String toString() {

+        return "RegionWidgetPreference{" +

+                "entityId=" + entityId +

+                ", name='" + name + '\'' +

+                ", value='" + value + '\'' +

+                '}';

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaTag.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaTag.java
new file mode 100644
index 0000000..598026a
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaTag.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+import org.apache.rave.portal.model.conversion.JpaWidgetTagConverter;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a group in the social database. The assumption in this object is that groups are
+ * associated with individuals and are used by those individuals to manage people.
+ */
+@Entity
+@Table(name = "tag")
+@Access(AccessType.FIELD)
+@NamedQueries({
+        @NamedQuery(name = JpaTag.GET_ALL, query = "select t from JpaTag t order by t.keyword asc"),
+        @NamedQuery(name = JpaTag.COUNT_ALL, query = "select count(t) from JpaTag t "),
+        @NamedQuery(name = JpaTag.GET_ALL_NOT_IN_WIDGET, query = "select tag from JpaTag tag where tag.keyword not in " +
+                "(select t.keyword from JpaTag t join t.widgets w where w.widgetId =:widgetId)"),
+
+        @NamedQuery(name = JpaTag.FIND_BY_KEYWORD, query = "select t from JpaTag t where UPPER(t.keyword) = UPPER(:keyword)")
+})
+
+public class JpaTag implements BasicEntity, Tag {
+
+    public static final String FIND_BY_KEYWORD = "findByKeyword";
+    public static final String GET_ALL = "getAll";
+    public static final String COUNT_ALL = "countAll";
+    public static final String GET_ALL_NOT_IN_WIDGET = "getAllNotInWidget";
+    public static final String KEYWORD_PARAM = "keyword";
+
+    @Autowired
+    private JpaWidgetTagConverter jpaWidgetTagConverter;
+
+    /**
+     * The internal object ID used for references to this object. Should be generated by the
+     * underlying storage mechanism
+     */
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "tagIdGenerator")
+    @TableGenerator(name = "tagIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "tag", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic
+    @Column(name = "keyword", unique = true)
+    private String keyword;
+
+    @OneToMany(mappedBy = "tag")
+    public List<JpaWidgetTag> widgets;
+
+
+    public JpaTag() {
+
+    }
+
+    public JpaTag(Long entityId, String keyword) {
+        this.entityId = entityId;
+        this.keyword = keyword;
+    }
+
+    public String getKeyword() {
+        return keyword;
+    }
+
+    public void setKeyword(String keyword) {
+        this.keyword = keyword;
+    }
+
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<WidgetTag> getWidgets() {
+        return ConvertingListProxyFactory.createProxyList(WidgetTag.class, widgets);
+    }
+
+    @Override
+    public void setWidgets(List<WidgetTag> widgets) {
+        if (this.widgets == null) {
+            this.widgets = new ArrayList<JpaWidgetTag>();
+        }
+        this.getWidgets().clear();
+        if (widgets != null) {
+            this.getWidgets().addAll(widgets);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        JpaTag tag = (JpaTag) o;
+
+        if (entityId != null ? !entityId.equals(tag.entityId) : tag.entityId != null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return entityId != null ? entityId.hashCode() : 0;
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaUser.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaUser.java
new file mode 100644
index 0000000..7434cb8
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaUser.java
@@ -0,0 +1,428 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+import org.apache.rave.portal.model.conversion.JpaConverter;
+import org.apache.rave.portal.model.impl.PersonImpl;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.security.core.GrantedAuthority;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * {@inheritDoc}
+ * <p/>
+ * A user of the system
+ */
+@Entity
+@Access(AccessType.FIELD)
+@NamedQueries({
+        @NamedQuery(name = JpaUser.USER_GET_BY_USERNAME, query = "select u from JpaUser u where u.username = :"+ JpaUser.PARAM_USERNAME),
+        @NamedQuery(name = JpaUser.USER_GET_BY_USER_EMAIL, query = "select u from JpaUser u where u.email = :"+ JpaUser.PARAM_EMAIL),
+        @NamedQuery(name = JpaUser.USER_GET_ALL, query = "select u from JpaUser u order by u.username asc"),
+        @NamedQuery(name = JpaUser.USER_GET_BY_FORGOT_PASSWORD_HASH, query = "select u from JpaUser u where u.forgotPasswordHash = :" + JpaUser.PARAM_FORGOT_PASSWORD_HASH),
+        @NamedQuery(name = JpaUser.USER_COUNT_ALL, query = "select count(u) from JpaUser u"),
+        @NamedQuery(name = JpaUser.USER_FIND_BY_USERNAME_OR_EMAIL, query = "select u from JpaUser u " +
+                "where lower(u.username) like :"+ JpaUser.PARAM_SEARCHTERM+" or lower(u.email) like :"+ JpaUser.PARAM_SEARCHTERM+" order by u.username asc"),
+        @NamedQuery(name = JpaUser.USER_COUNT_FIND_BY_USERNAME_OR_EMAIL, query = "select count(u) from JpaUser u " +
+                "where lower(u.username) like :"+ JpaUser.PARAM_SEARCHTERM+" or lower(u.email) like :"+ JpaUser.PARAM_SEARCHTERM),
+        @NamedQuery(name = JpaUser.USER_GET_ALL_FOR_ADDED_WIDGET, query = "select distinct(rw.region.page.owner) from JpaRegionWidget rw where rw.widget.entityId = :widgetId order by rw.region.page.owner.familyName, rw.region.page.owner.givenName")
+})
+@DiscriminatorValue("User")
+public class JpaUser extends JpaPerson implements BasicEntity, Serializable, User {
+    private static final long serialVersionUID = 1L;
+
+    public static final String USER_GET_BY_USERNAME = "User.getByUsername";
+    public static final String USER_GET_BY_USER_EMAIL = "User.getByUserEmail";
+    public static final String USER_GET_ALL = "User.getAll";
+    public static final String USER_COUNT_ALL = "User.countAll";
+    public static final String USER_FIND_BY_USERNAME_OR_EMAIL = "User.findByUsernameOrEmail";
+    public static final String USER_COUNT_FIND_BY_USERNAME_OR_EMAIL = "User.countFindByUsernameOrEmail";
+    public static final String USER_GET_COMMENTERS = "User.getCommenters";
+    public static final String USER_GET_ALL_FOR_ADDED_WIDGET = "User.getAllForAddedWidget";
+    public static final String USER_GET_BY_FORGOT_PASSWORD_HASH = "User.getByForgotPasswordHash";
+
+    public static final String PARAM_USERNAME = "username";
+    public static final String PARAM_FORGOT_PASSWORD_HASH = "forgotPasswordHash";
+    public static final String PARAM_EMAIL = "email";
+    public static final String PARAM_SEARCHTERM = "searchTerm";
+    public static final String PARAM_WIDGET_ID = "widgetId";
+
+
+    @Basic
+    @Column(name = "password")
+    private String password;
+
+    @Basic
+    @Column(name = "expired")
+    private boolean expired;
+
+    @Basic
+    @Column(name = "locked")
+    private boolean locked;
+
+    @Basic
+    @Column(name = "enabled")
+    private boolean enabled;
+
+    @Basic
+    @Column(name = "openid")
+    private String openId;
+
+    @Basic
+    @Column(name = "forgotPasswordHash", unique = true)
+    private String forgotPasswordHash;
+
+    @Basic
+    @Column(name = "password_hash_time")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date forgotPasswordTime;
+
+    @ManyToOne
+    @JoinColumn(name="default_page_layout_id")
+    private JpaPageLayout defaultPageLayout;
+
+    @Transient
+    private String confirmPassword;
+
+    @Transient
+    private String defaultPageLayoutCode;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = "user_authorities",
+            joinColumns =
+            @JoinColumn(name = "user_id", referencedColumnName = "entity_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "authority_id", referencedColumnName = "entity_id"))
+    private Collection<JpaAuthority> authorities;
+
+    @OneToMany(targetEntity=JpaPageUser.class, fetch = FetchType.LAZY, mappedBy="user", orphanRemoval=true)
+    private List<JpaPageUser> pageUsers;
+    
+    @OneToMany(targetEntity=JpaWidgetTag.class, fetch = FetchType.LAZY, mappedBy="user", orphanRemoval=true)
+    private List<JpaWidgetTag> widgetTags;
+
+    public JpaUser() {
+        this(null, null);
+    }
+
+    public JpaUser(Long entityId) {
+        this(entityId, null);
+    }
+
+    public JpaUser(Long entityId, String username) {
+        super();
+        this.entityId = entityId;
+        this.username = username;
+        this.authorities = new ArrayList<JpaAuthority>();
+    }
+
+    /**
+     * Gets the unique identifier for this user.
+     *
+     * @return The unique identifier for this user.
+     */
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public Collection<GrantedAuthority> getAuthorities() {
+        return CollectionUtils.<GrantedAuthority>toBaseTypedCollection(authorities);
+    }
+
+    @Override
+    public void addAuthority(Authority authority) {
+        JpaAuthority converted = JpaConverter.getInstance().convert(authority, Authority.class);
+        if (!authorities.contains(converted)) {
+            authorities.add(converted);
+        }
+        if (!authority.getUsers().contains(this)) {
+            authority.addUser(this);
+        }
+    }
+
+    @Override
+    public void removeAuthority(Authority authority) {
+        JpaAuthority converted = JpaConverter.getInstance().convert(authority, Authority.class);
+        if (authorities.contains(converted)) {
+            authorities.remove(converted);
+        }
+    }
+
+    @Override
+    public void setAuthorities(Collection<Authority> newAuthorities) {
+        this.getAuthorities().clear();
+        if(newAuthorities != null) {
+            this.getAuthorities().addAll(newAuthorities);
+        }
+    }
+
+    @Override
+    public String getPassword() {
+        return password;
+    }
+
+    @Override
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    @Override
+    public String getUsername() {
+        return username;
+    }
+
+    @Override
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return !locked;
+    }
+
+    @Override
+    public boolean isLocked() {
+        return locked;
+    }
+
+    @Override
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return !expired;
+    }
+
+    //REVIEW NOTE: Conflating Account and Credential (non)expiration seems likely to cause confusion at some point.
+    @Override
+    public boolean isAccountNonExpired() {
+        return isCredentialsNonExpired();
+    }
+
+    @Override
+    public boolean isExpired() {
+        return expired;
+    }
+
+    @Override
+    public void setExpired(boolean expired) {
+        this.expired = expired;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    //The following properties are specific to the user profile.
+    @Override
+    public String getEmail() {
+        return email;
+    }
+
+    @Override
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    @Override
+    public String getOpenId() {
+        return openId;
+    }
+
+    @Override
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
+    @Override
+    public String getForgotPasswordHash() {
+        return forgotPasswordHash;
+    }
+
+    @Override
+    public void setForgotPasswordHash(String forgotPasswordHash) {
+        this.forgotPasswordHash = forgotPasswordHash;
+    }
+
+    @Override
+    public Date getForgotPasswordTime() {
+        return forgotPasswordTime;
+    }
+
+    @Override
+    public void setForgotPasswordTime(Date forgotPasswordTime) {
+        this.forgotPasswordTime = forgotPasswordTime;
+    }
+
+    @Override
+    public PageLayout getDefaultPageLayout() {
+        return defaultPageLayout;
+    }
+
+    @Override
+    public void setDefaultPageLayout(PageLayout defaultPageLayout) {
+        this.defaultPageLayout = JpaConverter.getInstance().convert(defaultPageLayout, PageLayout.class);
+    }
+
+    @Override
+    public String getConfirmPassword() {
+		return confirmPassword;
+	}
+
+	@Override
+    public void setConfirmPassword(String confirmPassword) {
+		this.confirmPassword = confirmPassword;
+	}
+
+    public List<PageUser> getPageUsers() {
+        return ConvertingListProxyFactory.createProxyList(PageUser.class, pageUsers);
+    }
+
+    public void setPageUsers(List<PageUser> pageUsers) {
+        if(this.pageUsers == null) {
+            this.pageUsers = new ArrayList<JpaPageUser>();
+        }
+        this.getPageUsers().clear();
+        if(pageUsers != null) {
+            this.getPageUsers().addAll(pageUsers);
+        }
+    }
+
+    public List<WidgetTag> getWidgetTags() {
+        return ConvertingListProxyFactory.createProxyList(WidgetTag.class, widgetTags);
+    }
+
+    public void setWidgetTags(List<WidgetTag> widgetTags) {
+        if(this.widgetTags == null) {
+            this.widgetTags = new ArrayList<JpaWidgetTag>();
+        }
+        this.getWidgetTags().clear();
+        if(widgetTags != null) {
+            this.getWidgetTags().addAll(widgetTags);
+        }
+    }
+
+    @PreRemove
+    public void preRemove() {
+        for (JpaAuthority authority : authorities) {
+            authority.removeUser(this);
+        }
+        this.authorities = Collections.emptyList();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+
+        final JpaUser other = (JpaUser) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 67 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("User");
+        sb.append("{entityId=").append(entityId);
+        sb.append(", username='").append(username).append('\'');
+        sb.append(", expired=").append(expired);
+        sb.append(", locked=").append(locked);
+        sb.append(", enabled=").append(enabled);
+        sb.append(", email='").append(email).append('\'');
+        sb.append(", openId='").append(openId).append('\'');
+        sb.append(", authorities=[");
+        boolean first=true;
+        for (JpaAuthority a : authorities) {
+            if (!first) {
+                sb.append(',');
+            }
+            sb.append('\'').append(a.getAuthority()).append('\'');
+            first = false;
+        }
+        sb.append(']');
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public Person toPerson() {
+        PersonImpl p = new PersonImpl();
+        p.setAboutMe(this.getAboutMe());
+        p.setAdditionalName(this.getAdditionalName());
+        p.setAddresses(this.getAddresses());
+        p.setDisplayName(this.getDisplayName());
+        p.setEmail(this.getEmail());
+        p.setFamilyName(this.getFamilyName());
+        p.setFriends(this.getFriends());
+        p.setGivenName(this.getGivenName());
+        p.setHonorificPrefix(this.getHonorificPrefix());
+        p.setHonorificSuffix(this.getHonorificSuffix());
+        p.setOrganizations(this.getOrganizations());
+        p.setPreferredName(this.getPreferredName());
+        p.setProperties(this.getProperties());
+        p.setStatus(this.getStatus());
+        p.setUsername(this.getUsername());
+        return p;
+    }
+
+    @Override
+    public Long getId() {
+        return this.getEntityId();
+    }
+
+    public String getDefaultPageLayoutCode() {
+		return defaultPageLayoutCode;
+	}
+
+	public void setDefaultPageLayoutCode(String defaultPageLayoutCode) {
+		this.defaultPageLayoutCode = defaultPageLayoutCode;
+	}
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidget.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidget.java
new file mode 100644
index 0000000..24eebf7
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidget.java
@@ -0,0 +1,487 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.ConvertingListProxyFactory;
+import org.apache.rave.portal.model.conversion.JpaConverter;
+
+import javax.persistence.*;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A widget
+ */
+@XmlAccessorType(XmlAccessType.NONE)
+@Entity
+@Access(AccessType.FIELD)
+@Table(name = "widget")
+@NamedQueries({
+        @NamedQuery(name = JpaWidget.WIDGET_GET_ALL, query = JpaWidget.SELECT_W_FROM_WIDGET_W + JpaWidget.ORDER_BY_TITLE_ASC),
+        @NamedQuery(name = JpaWidget.WIDGET_COUNT_ALL, query = JpaWidget.SELECT_COUNT_W_FROM_WIDGET_W),
+
+        @NamedQuery(name = JpaWidget.WIDGET_GET_BY_OWNER,
+                query = JpaWidget.SELECT_W_FROM_WIDGET_W + JpaWidget.WHERE_CLAUSE_OWNER + JpaWidget.ORDER_BY_TITLE_ASC),
+        @NamedQuery(name = JpaWidget.WIDGET_COUNT_BY_OWNER,
+                query = JpaWidget.SELECT_COUNT_W_FROM_WIDGET_W + JpaWidget.WHERE_CLAUSE_OWNER),
+
+        @NamedQuery(name = JpaWidget.WIDGET_GET_BY_FREE_TEXT,
+                query = JpaWidget.SELECT_W_FROM_WIDGET_W + JpaWidget.WHERE_CLAUSE_FREE_TEXT + JpaWidget.ORDER_BY_TITLE_ASC),
+        @NamedQuery(name = JpaWidget.WIDGET_COUNT_BY_FREE_TEXT,
+                query = JpaWidget.SELECT_COUNT_W_FROM_WIDGET_W + JpaWidget.WHERE_CLAUSE_FREE_TEXT),
+
+        @NamedQuery(name = JpaWidget.WIDGET_GET_BY_STATUS,
+                query = JpaWidget.SELECT_W_FROM_WIDGET_W + JpaWidget.WHERE_CLAUSE_STATUS + JpaWidget.ORDER_BY_TITLE_ASC),
+        @NamedQuery(name = JpaWidget.WIDGET_COUNT_BY_STATUS,
+                query = JpaWidget.SELECT_COUNT_W_FROM_WIDGET_W + JpaWidget.WHERE_CLAUSE_STATUS),
+
+        @NamedQuery(name = JpaWidget.WIDGET_GET_BY_URL, query = JpaWidget.SELECT_W_FROM_WIDGET_W + JpaWidget.WHERE_CLAUSE_URL) ,
+
+        @NamedQuery(name = JpaWidget.WIDGET_GET_BY_TAG, query = JpaWidget.SELECT_W_FROM_WIDGET_W + JpaWidget.JOIN_TAGS+ JpaWidget.ORDER_BY_TITLE_ASC),
+        @NamedQuery(name = JpaWidget.WIDGET_COUNT_BY_TAG, query = JpaWidget.SELECT_COUNT_W_FROM_WIDGET_W + JpaWidget.JOIN_TAGS),
+        @NamedQuery(name = JpaWidget.WIDGET_UNASSIGN_OWNER, query = "UPDATE JpaWidget w SET w.owner = null WHERE w.owner.entityId = :owner")
+})
+public class JpaWidget implements BasicEntity, Serializable, Widget {
+    private static final long serialVersionUID = 1L;
+
+    public static final String PARAM_SEARCH_TERM = "searchTerm";
+    public static final String PARAM_STATUS = "widgetStatus";
+    public static final String PARAM_URL = "url";
+    public static final String PARAM_OWNER = "owner";
+    public static final String PARAM_TAG = "keyword";
+
+    public static final String WIDGET_GET_ALL = "Widget.getAll";
+    public static final String WIDGET_COUNT_ALL = "Widget.countAll";
+    public static final String WIDGET_GET_BY_OWNER = "Widget.getByOwner";
+    public static final String WIDGET_COUNT_BY_OWNER = "Widget.countByOwner";
+    public static final String WIDGET_GET_BY_FREE_TEXT = "Widget.getByFreeText";
+    public static final String WIDGET_COUNT_BY_FREE_TEXT = "Widget.countByFreeText";
+    public static final String WIDGET_GET_BY_STATUS = "Widget.getByStatus";
+    public static final String WIDGET_COUNT_BY_STATUS = "Widget.countByStatus";
+    public static final String WIDGET_GET_BY_URL = "Widget.getByUrl";
+    public static final String WIDGET_GET_BY_TAG = "Widget.getByTag";
+    public static final String WIDGET_COUNT_BY_TAG = "Widget.countByTag";
+    public static final String WIDGET_UNASSIGN_OWNER = "Widget.unassignOwner";
+
+    static final String SELECT_W_FROM_WIDGET_W = "SELECT w FROM JpaWidget w ";
+    static final String SELECT_COUNT_W_FROM_WIDGET_W = "SELECT count(w) FROM JpaWidget w ";
+
+    static final String WHERE_CLAUSE_FREE_TEXT =
+            " WHERE lower(w.title) LIKE :" + PARAM_SEARCH_TERM + " OR w.description LIKE :description";
+    static final String WHERE_CLAUSE_STATUS = " WHERE w.widgetStatus = :" + PARAM_STATUS;
+    static final String WHERE_CLAUSE_URL = " WHERE w.url = :" + PARAM_URL;
+    static final String WHERE_CLAUSE_OWNER = " WHERE w.owner = :" + PARAM_OWNER;
+    static final String WIDGET_TAG_BY_KEYWORD=" (select t.widgetId from JpaWidgetTag t where lower(t.tag.keyword)=:"+PARAM_TAG+")";
+    static final String JOIN_TAGS=" WHERE w.entityId in"+WIDGET_TAG_BY_KEYWORD;
+
+    static final String ORDER_BY_TITLE_ASC = " ORDER BY w.featured DESC, w.title ASC ";
+
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetIdGenerator")
+    @TableGenerator(name = "widgetIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    /*
+        TODO RAVE-234: Figure out what the OpenJPA strategy is for functionality provided by Eclisplink's @Convert
+     */
+    @XmlElement
+    @Basic
+    @Column(name = "title")
+    private String title;
+    //private InternationalString title;
+
+    @XmlElement
+    @Basic
+    @Column(name = "title_url")
+    private String titleUrl;
+
+    @XmlElement
+    @Basic
+    @Column(name = "url", unique = true)
+    private String url;
+
+    @Basic
+    @Column(name = "thumbnail_url")
+    private String thumbnailUrl;
+
+    @Basic
+    @Column(name = "screenshot_url")
+    private String screenshotUrl;
+
+    @XmlElement
+    @Basic
+    @Column(name = "type")
+    private String type;
+
+    @XmlElement
+    @Basic
+    @Column(name = "author")
+    private String author;
+
+    @XmlElement
+    @Basic
+    @Column(name = "author_email")
+    private String authorEmail;
+
+    @XmlElement
+    @Basic
+    @Column(name = "description")
+    @Lob
+    private String description;
+
+    @XmlElement(name = "status")
+    @Basic
+    @Column(name = "widget_status")
+    @Enumerated(EnumType.STRING)
+    private WidgetStatus widgetStatus;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinColumn(name = "widget_id", referencedColumnName = "entity_id")
+    private List<JpaWidgetComment> comments;
+
+    @ManyToOne
+    @JoinColumn(name = "owner_id")
+    private JpaUser owner;
+
+    @XmlElement
+    @Basic
+    @Column(name = "disable_rendering")
+    private boolean disableRendering;
+
+    @XmlElement
+    @Basic
+    @Column(name = "disable_rendering_message")
+    private String disableRenderingMessage;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinColumn(name = "widget_id", referencedColumnName = "entity_id")
+    private List<JpaWidgetRating> ratings;
+
+    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinColumn(name = "widget_id", referencedColumnName = "entity_id")
+    private List<JpaWidgetTag> tags;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name="widget_category",
+            joinColumns=@JoinColumn(name="widget_id", referencedColumnName = "entity_id"),
+            inverseJoinColumns=@JoinColumn(name="category_id", referencedColumnName = "entity_id")
+    )
+    @OrderBy("text")
+    private List<JpaCategory> categories;
+
+    @XmlElement
+    @Basic
+    @Column(name = "featured")
+    private boolean featured;
+
+    public JpaWidget() {
+    }
+
+    public JpaWidget(Long entityId, String url) {
+        this.entityId = entityId;
+        this.url = url;
+    }
+
+    /**
+     * Gets the persistence unique identifier
+     *
+     * @return id The ID of persisted object; null if not persisted
+     */
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    //See TODO RAVE-234
+//    public InternationalString getTitle() {
+//        return title;
+//    }
+//
+//    public void setTitle(InternationalString title) {
+//        this.title = title;
+//
+// }
+
+    @Override
+    public Long getId() {
+        return this.getEntityId();
+    }
+
+    @Override
+    public String getScreenshotUrl() {
+        return screenshotUrl;
+    }
+
+    @Override
+    public void setScreenshotUrl(String screenshotUrl) {
+        this.screenshotUrl = screenshotUrl;
+    }
+
+    @Override
+    public String getAuthor() {
+        return author;
+    }
+
+    @Override
+    public void setAuthor(String author) {
+        this.author = author;
+    }
+
+    @Override
+    public String getAuthorEmail() {
+        return authorEmail;
+    }
+
+    @Override
+    public void setAuthorEmail(String authorEmail) {
+        this.authorEmail = authorEmail;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public String getThumbnailUrl() {
+        return thumbnailUrl;
+    }
+
+    @Override
+    public void setThumbnailUrl(String thumbnailUrl) {
+        this.thumbnailUrl = thumbnailUrl;
+    }
+
+    @Override
+    public String getType() {
+        return type;
+    }
+
+    @Override
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    @Override
+    public String getTitle() {
+        return title;
+    }
+
+    @Override
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    @Override
+    public String getTitleUrl() {
+        return titleUrl;
+    }
+
+    @Override
+    public void setTitleUrl(String titleUrl) {
+        this.titleUrl = titleUrl;
+    }
+
+    @Override
+    public String getUrl() {
+        return url;
+    }
+
+    @Override
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    @Override
+    public WidgetStatus getWidgetStatus() {
+        return widgetStatus;
+    }
+
+    @Override
+    public void setWidgetStatus(WidgetStatus widgetStatus) {
+        this.widgetStatus = widgetStatus;
+    }
+
+    @Override
+    public List<WidgetComment> getComments() {
+        return ConvertingListProxyFactory.createProxyList(WidgetComment.class, comments);
+    }
+
+    @Override
+    public void setComments(List<WidgetComment> comments) {
+        if(this.comments == null) {
+            this.comments = new ArrayList<JpaWidgetComment>();
+        }
+        //Ensure that all operations go through the conversion proxy
+        this.getComments().clear();
+        if (comments != null) {
+            this.getComments().addAll(comments);
+        }
+    }
+
+    @Override
+    public User getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(User owner) {
+        this.owner = JpaConverter.getInstance().convert(owner, User.class);
+    }
+
+    @Override
+    public List<WidgetRating> getRatings() {
+        return ConvertingListProxyFactory.createProxyList(WidgetRating.class, this.ratings);
+    }
+
+    @Override
+    public void setRatings(List<WidgetRating> ratings) {
+        if (this.ratings == null) {
+            this.ratings = new ArrayList<JpaWidgetRating>();
+        }
+        //Ensure that all operations go through the conversion proxy
+        this.getRatings().clear();
+        if (ratings != null) {
+            this.getRatings().addAll(ratings);
+        }
+    }
+
+    @Override
+    public boolean isDisableRendering() {
+        return disableRendering;
+    }
+
+    @Override
+    public void setDisableRendering(boolean disableRendering) {
+        this.disableRendering = disableRendering;
+    }
+
+    @Override
+    public String getDisableRenderingMessage() {
+        return disableRenderingMessage;
+    }
+
+    @Override
+    public void setDisableRenderingMessage(String disableRenderingMessage) {
+        this.disableRenderingMessage = disableRenderingMessage;
+    }
+
+    @Override
+    public List<WidgetTag> getTags() {
+        return ConvertingListProxyFactory.createProxyList(WidgetTag.class, tags);
+    }
+
+    @Override
+    public void setTags(List<WidgetTag> tags) {
+        if(this.tags == null) {
+            this.tags = new ArrayList<JpaWidgetTag>();
+        }
+        //Ensure that all operations go through the conversion proxy
+        this.getTags().clear();
+        if(tags != null) {
+            this.getTags().addAll(tags);
+        }
+    }
+
+    @Override
+    public List<Category> getCategories() {
+        return ConvertingListProxyFactory.createProxyList(Category.class, categories);
+    }
+
+    @Override
+    public void setCategories(List<Category> categories) {
+        if (this.categories == null) {
+            this.categories = new ArrayList<JpaCategory>();
+        }
+        //Ensure that all operations go through the conversion proxy
+        this.getCategories().clear();
+        if (categories != null) {
+            this.getCategories().addAll(categories);
+        }
+    }
+
+    @Override
+    public boolean isFeatured() {
+        return featured;
+    }
+
+    @Override
+    public void setFeatured(boolean featured) {
+        this.featured = featured;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final JpaWidget other = (JpaWidget) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 97 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "Widget{" +
+                "entityId=" + entityId +
+                ", title='" + title + '\'' +
+                ", url='" + url + '\'' +
+                ", thumbnailUrl='" + thumbnailUrl + '\'' +
+                ", screenshotUrl='" + screenshotUrl + '\'' +
+                ", type='" + type + '\'' +
+                ", author='" + author + '\'' +
+                ", description='" + description + '\'' +
+                ", widgetStatus=" + widgetStatus + '\'' +
+                ", owner=" + owner + '\'' +
+                ", featured=" + featured + '\'' +
+                ", disable_rendering=" + disableRendering + '\'' +
+                ", disable_rendering_message=" + disableRenderingMessage +
+                '}';
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetComment.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetComment.java
new file mode 100644
index 0000000..dc24294
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetComment.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.rave.portal.model.conversion.JpaConverter;
+
+import javax.persistence.*;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * A comment for a widget.
+ */
+@Entity
+@Access(AccessType.FIELD)
+@Table(name = "widget_comment")
+@NamedQueries({
+        @NamedQuery(name = JpaWidgetComment.DELETE_ALL_BY_USER,
+                query="DELETE FROM JpaWidgetComment wc WHERE wc.user.entityId = :userId")
+})
+@XmlRootElement
+public class JpaWidgetComment implements BasicEntity, Serializable, WidgetComment {
+    public static final String DELETE_ALL_BY_USER = "WidgetComment.deleteAllByUserId";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetCommentIdGenerator")
+    @TableGenerator(name = "widgetCommentIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget_comment", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic
+    @Column(name = "widget_id")
+    private Long widgetId;
+
+    @ManyToOne(fetch=FetchType.EAGER)
+    @JoinColumn(name="user_id")
+    private JpaUser user;
+
+    @Basic
+    @Column(name = "text") @Lob
+    private String text;
+
+    @Basic
+    @Column(name ="last_modified_date")
+    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
+    private Date lastModifiedDate;
+
+    @Basic
+    @Column(name ="created_date")
+    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
+    private Date createdDate;
+
+    public JpaWidgetComment() {
+
+    }
+
+    public JpaWidgetComment(Long entityId, Long widgetId, JpaUser user, String text, Date lastModified, Date created) {
+        this.entityId = entityId;
+        this.widgetId = widgetId;
+        this.user = user;
+        this.text = text;
+        this.lastModifiedDate = lastModified;
+        this.createdDate = created;
+    }
+
+    @Override
+    public Long getId() {
+        return getEntityId();
+    }
+
+    @Override
+    public void setId(Long entityId) {
+        setEntityId(entityId);
+    }
+
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+
+    @Override
+    public Long getWidgetId() {
+        return widgetId;
+    }
+
+    @Override
+    public void setWidgetId(Long widgetId) {
+        this.widgetId = widgetId;
+    }
+
+    @Override
+    public User getUser() {
+        return user;
+    }
+
+    @Override
+    public void setUser(User user) {
+        this.user = JpaConverter.getInstance().convert(user, User.class);
+    }
+
+    @Override
+    public String getText() {
+        return text;
+    }
+
+    @Override
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    @Override
+    public Date getLastModifiedDate() {
+        return lastModifiedDate;
+    }
+
+    @Override
+    public void setLastModifiedDate(Date lastModified) {
+        this.lastModifiedDate = lastModified;
+    }
+
+    @Override
+    public Date getCreatedDate() {
+        return createdDate;
+    }
+
+    @Override
+    public void setCreatedDate(Date created) {
+        this.createdDate = created;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null || getClass() != obj.getClass()) return false;
+        JpaWidgetComment comment = (JpaWidgetComment) obj;
+        if (entityId != null ? !entityId.equals(comment.entityId) : comment.entityId != null) return false;
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 79 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "WidgetComment{" +
+                "entityId=" + entityId +
+                ", widgetId=" + widgetId +
+                ", text='" + text + '\'' +
+                '}';
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetRating.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetRating.java
new file mode 100644
index 0000000..9ee77dc
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetRating.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model;
+
+import org.apache.rave.persistence.BasicEntity;
+
+import javax.persistence.*;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+
+/**
+ * A Rating for a Widget
+ */
+@Entity
+@Access(AccessType.FIELD)
+@Table(name = "widget_rating")
+@NamedQueries ({
+        @NamedQuery(name = JpaWidgetRating.WIDGET_ALL_TOTAL_LIKES,
+                query = "SELECT COUNT(wr) total, wr.widgetId widgetIt FROM JpaWidgetRating wr WHERE wr.score = 10 GROUP BY wr.widgetId"),
+        @NamedQuery(name = JpaWidgetRating.WIDGET_TOTAL_LIKES,
+                query = "SELECT COUNT(wr) FROM JpaWidgetRating wr WHERE wr.widgetId = :widgetId AND wr.score = 10"),
+        @NamedQuery(name = JpaWidgetRating.WIDGET_ALL_TOTAL_DISLIKES,
+                query = "SELECT COUNT(wr) total, wr.widgetId widgetId FROM JpaWidgetRating wr WHERE wr.score = 0 GROUP BY wr.widgetId"),
+        @NamedQuery(name = JpaWidgetRating.WIDGET_TOTAL_DISLIKES,
+                query = "SELECT COUNT(wr) FROM JpaWidgetRating wr WHERE wr.widgetId = :widgetId AND wr.score = 0"),
+        @NamedQuery(name = JpaWidgetRating.WIDGET_ALL_USER_RATINGS,
+                query = "SELECT wr FROM JpaWidgetRating wr WHERE wr.userId = :userId"),
+        @NamedQuery(name = JpaWidgetRating.WIDGET_RATING_BY_WIDGET_AND_USER,
+                query = "SELECT wr FROM JpaWidgetRating wr WHERE wr.widgetId = :widgetId AND wr.userId = :userId"),
+        @NamedQuery(name = JpaWidgetRating.WIDGET_USER_RATING,
+                query = "SELECT wr.score FROM JpaWidgetRating wr WHERE wr.widgetId = :widgetId AND wr.userId = :userId"),
+        @NamedQuery(name = JpaWidgetRating.DELETE_ALL_BY_USER,
+                query="DELETE FROM JpaWidgetRating wr WHERE wr.userId = :userId")
+})
+@XmlRootElement
+public class JpaWidgetRating implements BasicEntity, Serializable, WidgetRating {
+
+    public static final String WIDGET_ALL_TOTAL_LIKES = "widget_all_total_likes";
+    public static final String WIDGET_TOTAL_LIKES = "widget_total_likes";
+    public static final String WIDGET_ALL_TOTAL_DISLIKES = "widget_all_total_dislikes";
+    public static final String WIDGET_TOTAL_DISLIKES = "widget_total_dislikes";
+    public static final String WIDGET_ALL_USER_RATINGS = "widget_all_user_ratings";
+    public static final String WIDGET_RATING_BY_WIDGET_AND_USER = "widget_rating_by_widget_and_user";
+    public static final String WIDGET_USER_RATING = "widget_user_rating";
+    public static final String DELETE_ALL_BY_USER = "delete_all_for_user";
+
+    public static final String PARAM_WIDGET_ID = "widgetId";
+    public static final String PARAM_USER_ID = "userId";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetRatingIdGenerator")
+    @TableGenerator(name = "widgetRatingIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget_rating", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+    
+    @Basic
+    @Column(name = "widget_id")
+    private Long widgetId;
+    
+    @Basic
+    @Column(name = "user_id")
+    private Long userId;
+    
+    @Basic
+    @Column(name = "score")
+    private Integer score;
+    
+    public static final Integer LIKE = 10; 
+    public static final Integer DISLIKE = 0;
+    public static final Integer UNSET = -1;
+
+    public JpaWidgetRating() {
+        
+    }
+    
+    public JpaWidgetRating(Long entityId, Long widgetId, Long userId, Integer score) {
+        this.entityId = entityId;
+        this.widgetId = widgetId;
+        this.userId = userId;
+        this.score = score;
+    }
+    
+    /**
+     * Gets the persistence unique identifier
+     *
+     * @return id The ID of persisted object; null if not persisted
+     */
+    @Override
+    public Long getEntityId() {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(Long entityId) {
+        this.entityId = entityId;
+    }
+    
+    @Override
+    public Long getWidgetId() {
+        return widgetId;
+    }
+
+    @Override
+    public void setWidgetId(Long widgetId) {
+        this.widgetId = widgetId;
+    }
+    
+    @Override
+    public Long getUserId() {
+        return userId;
+    }
+
+    @Override
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+    
+    @Override
+    public Integer getScore() {
+        return score;
+    }
+
+    @Override
+    public void setScore(Integer value) {
+        this.score = value;
+    }
+
+    @Override
+    public Long getId() {
+        return this.getEntityId();
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.setEntityId(id);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 59 * hash + (this.entityId != null ? this.entityId.hashCode() : 0);
+        return hash;
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final JpaWidgetRating other = (JpaWidgetRating) obj;
+        if (this.entityId != other.entityId && (this.entityId == null || !this.entityId.equals(other.entityId))) {
+            return false;
+        }
+        return true;
+    }
+    
+    @Override
+    public String toString() {
+        return "WidgetRating{" +
+                "entityId=" + entityId +
+                ", widgetId=" + widgetId + 
+                ", userId=" + userId + 
+                ", score=" + score + 
+                '}';
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetTag.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetTag.java
new file mode 100644
index 0000000..b5230df
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/JpaWidgetTag.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * 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.rave.portal.model;
+
+import org.apache.rave.portal.model.conversion.JpaConverter;
+
+import javax.persistence.*;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Date;
+/**
+ * A tag for a widget.
+ */
+@Entity
+@Table(name = "widget_tag")
+@Access(AccessType.FIELD)
+@XmlRootElement
+@NamedQueries({
+        @NamedQuery(name = JpaWidgetTag.FIND_BY_WIDGET_AND_KEYWORD, query = "select t from JpaWidgetTag t where t.widgetId=:widgetId and UPPER(t.tag.keyword) = UPPER(:keyword)")
+})
+public class JpaWidgetTag implements WidgetTag, Serializable {
+
+    public static final String FIND_BY_WIDGET_AND_KEYWORD = "findByWidgetAndKeyword";
+    public static final String WIDGET_ID_PARAM = "widgetId";
+    public static final String TAG_KEYWORD_PARAM = "keyword";
+
+    @Id
+    @Column(name = "entity_id")
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "widgetTagIdGenerator")
+    @TableGenerator(name = "widgetTagIdGenerator", table = "RAVE_PORTAL_SEQUENCES", pkColumnName = "SEQ_NAME",
+            valueColumnName = "SEQ_COUNT", pkColumnValue = "widget_tag", allocationSize = 1, initialValue = 1)
+    private Long entityId;
+
+    @Basic
+    @Column(name = "widget_id")
+    private Long widgetId;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = "user_id")
+    private JpaUser user;
+
+    @ManyToOne(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
+    @JoinColumn(name = "tag_id")
+    private JpaTag tag;
+
+    @Basic
+    @Column(name = "created_date")
+    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
+    private Date createdDate;
+
+    public JpaWidgetTag() {}
+
+    public JpaWidgetTag(long id, long widgetId, JpaUser user, Date date, JpaTag tag) {
+        this.entityId = id;
+        this.widgetId = widgetId;
+        this.user = user;
+        this.createdDate = date;
+        this.tag = tag;
+    }
+
+    public Long getEntityId(){
+        return this.entityId;
+    }
+    
+    public void setEntityId(Long id){
+        this.entityId = id;
+    }
+    
+    @Override
+    public Long getWidgetId() {
+        return this.widgetId;
+    }
+
+    @Override
+    public void setWidgetId(Long id) {
+        this.widgetId = id;
+    }
+
+    @Override
+    public User getUser() {
+        return this.user;
+    }
+
+    @Override
+    public void setUser(User user) {
+        this.user = JpaConverter.getInstance().convert(user, User.class);
+    }
+
+    @Override
+    public Tag getTag() {
+        return this.tag;
+    }
+
+    @Override
+    public void setTag(Tag tag) {
+        this.tag = JpaConverter.getInstance().convert(tag, Tag.class);
+    }
+
+    @Override
+    public Date getCreatedDate() {
+        return this.createdDate;
+    }
+
+    @Override
+    public void setCreatedDate(Date date) {
+        this.createdDate = date;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof JpaWidgetTag)) return false;
+
+        JpaWidgetTag that = (JpaWidgetTag) o;
+
+        if (createdDate != null ? !createdDate.equals(that.createdDate) : that.createdDate != null) return false;
+        if (tag != null ? !tag.equals(that.tag) : that.tag != null) return false;
+        if (user != null ? !user.equals(that.user) : that.user != null) return false;
+        if (widgetId != null ? !widgetId.equals(that.widgetId) : that.widgetId != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = widgetId != null ? widgetId.hashCode() : 0;
+        result = 31 * result + (user != null ? user.hashCode() : 0);
+        result = 31 * result + (tag != null ? tag.hashCode() : 0);
+        result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb=new StringBuilder("WidgetTag") ;
+        sb.append("{").append("entityId=").append(entityId).append( ", widgetId=").append(widgetId);
+        if (tag!=null) sb.append("tag keyword=").append(tag.getKeyword());
+        sb.append("}") ;
+        return sb.toString();
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/ConvertingListProxyFactory.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/ConvertingListProxyFactory.java
new file mode 100644
index 0000000..7ca3fc9
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/ConvertingListProxyFactory.java
@@ -0,0 +1,62 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Creates a {@link java.util.List} proxy that converts the added object to an entity
+ */
+@Component
+public class ConvertingListProxyFactory {
+
+    @SuppressWarnings("unchecked")
+    public static <E, T extends E> List<E> createProxyList(Class<E> targetType, List<T> underlyingList) {
+        // ensure the list is not null by creating an empty list to prevent unnecessary downstream NullPointerExceptions
+        if (underlyingList == null) {
+            underlyingList = new ArrayList<T>();
+        }
+        return (List) Proxy.newProxyInstance(ConvertingListProxyFactory.class.getClassLoader(),
+                new Class<?>[]{List.class},
+                new ConvertingListInvocationHandler<E, T>(underlyingList, targetType));
+    }
+
+    public static class ConvertingListInvocationHandler<S,T> implements InvocationHandler {
+
+        public static final String ADD_METHOD = "add";
+        public static final String SET_METHOD = "set";
+        public static final String ADD_ALL_METHOD = "addAll";
+
+        private List<T> underlying;
+        private Class<S> targetClass;
+
+        public ConvertingListInvocationHandler(List<T> underlying, Class<S> targetClass) {
+            this.underlying = underlying;
+            this.targetClass = targetClass;
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable {
+            String methodName = method.getName();
+            int convertIndex = method.getParameterTypes().length == 1 ? 0 : 1;
+            if(ADD_METHOD.equals(methodName) || SET_METHOD.equals(methodName)) {
+                parameters[convertIndex] = JpaConverter.getInstance().convert((S)parameters[convertIndex], targetClass);
+            } else if(ADD_ALL_METHOD.equals(methodName)) {
+                convertAll((List)parameters[convertIndex]);
+            }
+            return method.invoke(underlying, parameters);
+        }
+
+        @SuppressWarnings("unchecked")
+        private void convertAll(List<S> parameter) {
+            for (int i = 0; i < parameter.size(); i++) {
+                parameter.set(i, (S) JpaConverter.getInstance().convert(parameter.get(i), targetClass));
+            }
+        }
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaAddressConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaAddressConverter.java
new file mode 100644
index 0000000..78953ee
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaAddressConverter.java
@@ -0,0 +1,62 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.Address;
+import org.apache.rave.portal.model.JpaAddress;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+/**
+ * Converts an Address to a JpaAddress
+ */
+@Component
+public class JpaAddressConverter implements ModelConverter<Address, JpaAddress> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Address> getSourceType() {
+        return Address.class;
+    }
+
+    @Override
+    public JpaAddress convert(Address source) {
+        return source instanceof JpaAddress ? (JpaAddress) source : createEntity(source);
+    }
+
+    private JpaAddress createEntity(Address source) {
+        JpaAddress converted = null;
+        if (source != null) {
+            TypedQuery<JpaAddress> query = manager.createNamedQuery(JpaAddress.FIND_BY_STREET_CITY_COUNTRY, JpaAddress.class);
+            query.setParameter(JpaAddress.STREET_PARAM, source.getStreetAddress());
+            query.setParameter(JpaAddress.CITY_PARAM, source.getLocality());
+            query.setParameter(JpaAddress.COUNTRY_PARAM, source.getCountry());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaAddress();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Address source, JpaAddress converted) {
+        converted.setCountry(source.getCountry());
+        converted.setLatitude(source.getLatitude());
+        converted.setLongitude(source.getLongitude());
+        converted.setLocality(source.getLocality());
+        converted.setPostalCode(source.getPostalCode());
+        converted.setRegion(source.getRegion());
+        converted.setStreetAddress(source.getStreetAddress());
+        converted.setQualifier(source.getQualifier());
+        converted.setFormatted(source.getFormatted());
+        converted.setPrimary(source.getPrimary());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaApplicationDataConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaApplicationDataConverter.java
new file mode 100644
index 0000000..af6d757
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaApplicationDataConverter.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.ApplicationData;
+import org.apache.rave.portal.model.JpaApplicationData;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts a ApplicationData to a JpaApplicationData
+ */
+@Component
+public class JpaApplicationDataConverter implements ModelConverter<ApplicationData, JpaApplicationData> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<ApplicationData> getSourceType() {
+        return ApplicationData.class;
+    }
+
+    @Override
+    public JpaApplicationData convert(ApplicationData source) {
+        return source instanceof JpaApplicationData ? (JpaApplicationData) source : createEntity(source);
+    }
+
+    private JpaApplicationData createEntity(ApplicationData source) {
+        JpaApplicationData converted = null;
+        if (source != null) {
+            converted = manager.find(JpaApplicationData.class, source.getId());
+            if (converted == null) {
+                converted = new JpaApplicationData();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(ApplicationData source, JpaApplicationData converted) {
+        converted.setEntityId(source.getId());
+        converted.setId(source.getId());
+        converted.setAppUrl(source.getAppUrl());
+        converted.setUserId(source.getUserId());
+        converted.setData(source.getData());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaAuthorityConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaAuthorityConverter.java
new file mode 100644
index 0000000..43254e2
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaAuthorityConverter.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.JpaAuthority;
+import org.apache.rave.portal.model.User;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+@Component
+public class JpaAuthorityConverter implements ModelConverter<Authority, JpaAuthority> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Authority> getSourceType() {
+        return Authority.class;
+    }
+
+    @Override
+    public JpaAuthority convert(Authority source) {
+        return source instanceof JpaAuthority ? (JpaAuthority) source : createEntity(source);
+    }
+
+    private JpaAuthority createEntity(Authority source) {
+        JpaAuthority converted = null;
+        if (source != null) {
+            TypedQuery<JpaAuthority> query = manager.createNamedQuery(JpaAuthority.GET_BY_AUTHORITY_NAME, JpaAuthority.class);
+            query.setParameter(JpaAuthority.PARAM_AUTHORITY_NAME, source.getAuthority());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaAuthority();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Authority source, JpaAuthority converted) {
+        converted.setDefaultForNewUser(source.isDefaultForNewUser());
+        converted.setAuthority(source.getAuthority());
+        for(User user : source.getUsers()) {
+            converted.addUser(user);
+        }
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaCategoryConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaCategoryConverter.java
new file mode 100644
index 0000000..9280b93
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaCategoryConverter.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.Category;
+import org.apache.rave.portal.model.JpaCategory;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts a Category to a JpaCategory
+ */
+@Component
+public class JpaCategoryConverter implements ModelConverter<Category, JpaCategory> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Category> getSourceType() {
+        return Category.class;
+    }
+
+    @Override
+    public JpaCategory convert(Category source) {
+        return source instanceof JpaCategory ? (JpaCategory) source : createEntity(source);
+    }
+
+    private JpaCategory createEntity(Category source) {
+        JpaCategory converted = null;
+        if (source != null) {
+            converted = manager.find(JpaCategory.class, source.getId());
+            if (converted == null) {
+                converted = new JpaCategory();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Category source, JpaCategory converted) {
+        converted.setEntityId(source.getId());
+        converted.setId(source.getId());
+        converted.setCreatedDate(source.getCreatedDate());
+        converted.setCreatedUser(source.getCreatedUser());
+        converted.setLastModifiedDate(source.getLastModifiedDate());
+        converted.setLastModifiedUser(source.getLastModifiedUser());
+        converted.setText(source.getText());
+        converted.setWidgets(source.getWidgets());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaConverter.java
new file mode 100644
index 0000000..d9b76d9
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaConverter.java
@@ -0,0 +1,57 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Converts objects into their JPA representations by delegating to wired in components
+ */
+@Component
+public class JpaConverter {
+    //Workaround for inability to access spring context without a lot of machinery
+    //Will allow for a getInstance method to be called.  this is needed because the
+    //Converters are all Spring beans with their own dependencies.
+    private static JpaConverter instance;
+
+    Map<Class<?>, ModelConverter> converterMap;
+
+    @Autowired
+    JpaConverter(List<ModelConverter> converters) {
+        converterMap = new HashMap<Class<?>, ModelConverter>();
+        for(ModelConverter converter : converters) {
+            converterMap.put(converter.getSourceType(), converter);
+        }
+        instance = this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <S, T> T convert(S source, Class<S> clazz) {
+        if(converterMap.containsKey(clazz)) {
+            return (T)converterMap.get(clazz).convert(source);
+        } else {
+            throw new IllegalArgumentException("No ModelConverter found for type " + clazz);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public <S,T> ModelConverter<S, T> getConverter(Class<S> clazz) {
+        return converterMap.get(clazz);
+    }
+    
+    protected static boolean isInstanceSet() {
+        return instance != null;
+    }
+
+    public static JpaConverter getInstance() {
+        if(instance == null) {
+            throw new IllegalStateException("Conversion factory not set by the Spring context");
+        }
+        return instance;
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaGroupConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaGroupConverter.java
new file mode 100644
index 0000000..12d81e5
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaGroupConverter.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.Group;
+import org.apache.rave.portal.model.JpaGroup;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+@Component
+public class JpaGroupConverter implements ModelConverter<Group, JpaGroup> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Group> getSourceType() {
+        return Group.class;
+    }
+
+    @Override
+    public JpaGroup convert(Group source) {
+        return source instanceof JpaGroup ? (JpaGroup) source : createEntity(source);
+    }
+
+    private JpaGroup createEntity(Group source) {
+        JpaGroup converted = null;
+        if (source != null) {
+            TypedQuery<JpaGroup> query = manager.createNamedQuery(JpaGroup.FIND_BY_TITLE, JpaGroup.class);
+            query.setParameter(JpaGroup.GROUP_ID_PARAM, source.getTitle());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaGroup();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Group source, JpaGroup converted) {
+        converted.setDescription(source.getDescription());
+        converted.setTitle(source.getTitle());
+        converted.setOwner(source.getOwner());
+        converted.setMembers(source.getMembers());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOAuthConsumerStoreConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOAuthConsumerStoreConverter.java
new file mode 100644
index 0000000..38ac188
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOAuthConsumerStoreConverter.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaOAuthConsumerStore;
+import org.apache.rave.portal.model.OAuthConsumerStore;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts a OAuthConsumerStore to a JpaOAuthConsumerStore
+ */
+@Component
+public class JpaOAuthConsumerStoreConverter implements ModelConverter<OAuthConsumerStore, JpaOAuthConsumerStore> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<OAuthConsumerStore> getSourceType() {
+        return OAuthConsumerStore.class;
+    }
+
+    @Override
+    public JpaOAuthConsumerStore convert(OAuthConsumerStore source) {
+        return source instanceof JpaOAuthConsumerStore ? (JpaOAuthConsumerStore) source : createEntity(source);
+    }
+
+    private JpaOAuthConsumerStore createEntity(OAuthConsumerStore source) {
+        JpaOAuthConsumerStore converted = null;
+        if (source != null) {
+            converted = manager.find(JpaOAuthConsumerStore.class, source.getId());
+            if (converted == null) {
+                converted = new JpaOAuthConsumerStore();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(OAuthConsumerStore source, JpaOAuthConsumerStore converted) {
+        converted.setEntityId(source.getId());
+        converted.setId(source.getId());
+        converted.setServiceName(source.getServiceName());
+        converted.setCallbackUrl(source.getCallbackUrl());
+        converted.setConsumerKey(source.getConsumerKey());
+        converted.setConsumerSecret(source.getConsumerSecret());
+        converted.setGadgetUri(source.getGadgetUri());
+        converted.setKeyName(source.getKeyName());
+        converted.setKeyType(source.getKeyType());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOAuthTokenInfoConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOAuthTokenInfoConverter.java
new file mode 100644
index 0000000..6440f6f
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOAuthTokenInfoConverter.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaOAuthTokenInfo;
+import org.apache.rave.portal.model.OAuthTokenInfo;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts a OAuthTokenInfo to a JpaOAuthTokenInfo
+ */
+@Component
+public class JpaOAuthTokenInfoConverter implements ModelConverter<OAuthTokenInfo, JpaOAuthTokenInfo> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<OAuthTokenInfo> getSourceType() {
+        return OAuthTokenInfo.class;
+    }
+
+    @Override
+    public JpaOAuthTokenInfo convert(OAuthTokenInfo source) {
+        return source instanceof JpaOAuthTokenInfo ? (JpaOAuthTokenInfo) source : createEntity(source);
+    }
+
+    private JpaOAuthTokenInfo createEntity(OAuthTokenInfo source) {
+        JpaOAuthTokenInfo converted = null;
+        if (source != null) {
+            converted = manager.find(JpaOAuthTokenInfo.class, source.getId());
+            if (converted == null) {
+                converted = new JpaOAuthTokenInfo();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(OAuthTokenInfo source, JpaOAuthTokenInfo converted) {
+        converted.setEntityId(source.getId());
+        converted.setId(source.getId());
+        converted.setAccessToken(source.getAccessToken());
+        converted.setAppUrl(source.getAppUrl());
+        converted.setModuleId(source.getModuleId());
+        converted.setServiceName(source.getServiceName());
+        converted.setSessionHandle(source.getSessionHandle());
+        converted.setTokenExpireMillis(source.getTokenExpireMillis());
+        converted.setTokenName(source.getTokenName());
+        converted.setTokenSecret(source.getTokenSecret());
+        converted.setUserId(source.getUserId());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOrganizationConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOrganizationConverter.java
new file mode 100644
index 0000000..e15ec57
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaOrganizationConverter.java
@@ -0,0 +1,61 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaOrganization;
+import org.apache.rave.portal.model.Organization;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+/**
+ * Converts an Address to a JpaAddress
+ */
+@Component
+public class JpaOrganizationConverter implements ModelConverter<Organization, JpaOrganization> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Organization> getSourceType() {
+        return Organization.class;
+    }
+
+    @Override
+    public JpaOrganization convert(Organization source) {
+        return source instanceof JpaOrganization ? (JpaOrganization) source : createEntity(source);
+    }
+
+    private JpaOrganization createEntity(Organization source) {
+        JpaOrganization converted = null;
+        if (source != null) {
+            TypedQuery<JpaOrganization> query = manager.createNamedQuery(JpaOrganization.FIND_BY_NAME, JpaOrganization.class);
+            query.setParameter(JpaOrganization.NAME_PARAM, source.getName());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaOrganization();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Organization source, JpaOrganization converted) {
+        converted.setAddress(source.getAddress());
+        converted.setDescription(source.getDescription());
+        converted.setEndDate(source.getEndDate());
+        converted.setField(source.getField());
+        converted.setName(source.getName());
+        converted.setStartDate(source.getStartDate());
+        converted.setSubField(source.getSubField());
+        converted.setTitle(source.getTitle());
+        converted.setWebpage(source.getWebpage());
+        converted.setQualifier(source.getQualifier());
+        converted.setPrimary(source.getPrimary());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java
new file mode 100644
index 0000000..ee79cd3
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageConverter.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPage;
+import org.apache.rave.portal.model.Page;
+import org.apache.rave.portal.model.PageUser;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts a Page to a JpaPage
+ */
+@Component
+public class JpaPageConverter implements ModelConverter<Page, JpaPage> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Page> getSourceType() {
+        return Page.class;
+    }
+
+    @Override
+    public JpaPage convert(Page source) {
+        return source instanceof JpaPage ? (JpaPage) source : createEntity(source);
+    }
+
+    private JpaPage createEntity(Page source) {
+        JpaPage converted = null;
+        if (source != null) {
+            converted = manager.find(JpaPage.class, source.getId());
+            if (converted == null) {
+                converted = new JpaPage();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Page source, JpaPage converted) {
+        replacePageReferences(source, converted);
+        converted.setEntityId(source.getId());
+        converted.setId(source.getId());
+        converted.setMembers(source.getMembers());
+        converted.setName(source.getName());
+        converted.setOwner(source.getOwner());
+        converted.setPageLayout(source.getPageLayout());
+        converted.setPageType(source.getPageType());
+        converted.setParentPage(source.getParentPage());
+        converted.setRegions(source.getRegions());
+        converted.setSubPages(source.getSubPages());
+    }
+
+    private void replacePageReferences(Page source, JpaPage converted) {
+        if(source.getMembers() != null) {
+            for(PageUser user : source.getMembers()) {
+                user.setPage(converted);
+            }
+        }
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageLayoutConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageLayoutConverter.java
new file mode 100644
index 0000000..edfdfa2
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageLayoutConverter.java
@@ -0,0 +1,50 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPageLayout;
+import org.apache.rave.portal.model.PageLayout;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+@Component
+public class JpaPageLayoutConverter implements ModelConverter<PageLayout, JpaPageLayout> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<PageLayout> getSourceType() {
+        return PageLayout.class;
+    }
+
+    @Override
+    public JpaPageLayout convert(PageLayout source) {
+        return source instanceof JpaPageLayout ? (JpaPageLayout) source : createEntity(source);
+    }
+
+    private JpaPageLayout createEntity(PageLayout source) {
+        JpaPageLayout converted = null;
+        if (source != null) {
+            TypedQuery<JpaPageLayout> query = manager.createNamedQuery(JpaPageLayout.PAGELAYOUT_GET_BY_LAYOUT_CODE, JpaPageLayout.class);
+            query.setParameter(JpaPageLayout.CODE_PARAM, source.getCode());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaPageLayout();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(PageLayout source, JpaPageLayout converted) {
+        converted.setCode(source.getCode());
+        converted.setNumberOfRegions(source.getNumberOfRegions());
+        converted.setRenderSequence(source.getRenderSequence());
+        converted.setUserSelectable(source.isUserSelectable());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateConverter.java
new file mode 100644
index 0000000..5e7efd5
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateConverter.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPageTemplate;
+import org.apache.rave.portal.model.PageTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+@Component
+public class JpaPageTemplateConverter implements ModelConverter<PageTemplate, JpaPageTemplate> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<PageTemplate> getSourceType() {
+        return PageTemplate.class;
+    }
+
+    @Override
+    public JpaPageTemplate convert(PageTemplate source) {
+        return source instanceof JpaPageTemplate ? (JpaPageTemplate)source : createEntity(source);
+    }
+
+    private JpaPageTemplate createEntity(PageTemplate source) {
+        JpaPageTemplate converted = null;
+        if(source != null) {
+            converted = manager.find(JpaPageTemplate.class, source.getId());
+
+            if(converted == null) {
+                converted = new JpaPageTemplate();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(PageTemplate source, JpaPageTemplate converted) {
+        converted.setEntityId(source.getId());
+        converted.setName(source.getName());
+        converted.setDescription(source.getDescription());
+        converted.setPageType(source.getPageType());
+        converted.setParentPageTemplate(source.getParentPageTemplate());
+        converted.setSubPageTemplates(source.getSubPageTemplates());
+        converted.setPageLayout(source.getPageLayout());
+        converted.setPageTemplateRegions(source.getPageTemplateRegions());
+        converted.setRenderSequence(source.getRenderSequence());
+        converted.setDefaultTemplate(source.isDefaultTemplate());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateRegionConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateRegionConverter.java
new file mode 100644
index 0000000..96ce54b
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateRegionConverter.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPageTemplateRegion;
+import org.apache.rave.portal.model.PageTemplateRegion;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+@Component
+public class JpaPageTemplateRegionConverter implements ModelConverter<PageTemplateRegion, JpaPageTemplateRegion> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<PageTemplateRegion> getSourceType() {
+        return PageTemplateRegion.class;
+    }
+
+    @Override
+    public JpaPageTemplateRegion convert(PageTemplateRegion source) {
+        return source instanceof JpaPageTemplateRegion ? (JpaPageTemplateRegion) source : createEntity(source);
+    }
+
+    private JpaPageTemplateRegion createEntity(PageTemplateRegion source) {
+        JpaPageTemplateRegion converted = null;
+
+        if (source != null) {
+            converted = manager.find(JpaPageTemplateRegion.class, source.getId());
+
+            if (converted == null) {
+                converted = new JpaPageTemplateRegion();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(PageTemplateRegion source, JpaPageTemplateRegion converted) {
+        converted.setEntityId(source.getId());
+        converted.setRenderSequence(source.getRenderSequence());
+        converted.setPageTemplateWidgets(source.getPageTemplateWidgets());
+        converted.setPageTemplate(source.getPageTemplate());
+        converted.setLocked(source.isLocked());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateWidgetConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateWidgetConverter.java
new file mode 100644
index 0000000..4c90241
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageTemplateWidgetConverter.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPageTemplateWidget;
+import org.apache.rave.portal.model.PageTemplateWidget;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+@Component
+public class JpaPageTemplateWidgetConverter implements ModelConverter<PageTemplateWidget, JpaPageTemplateWidget> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<PageTemplateWidget> getSourceType() {
+        return PageTemplateWidget.class;
+    }
+
+    @Override
+    public JpaPageTemplateWidget convert(PageTemplateWidget source) {
+        return source instanceof JpaPageTemplateWidget ? (JpaPageTemplateWidget) source : createEntity(source);
+    }
+
+    private JpaPageTemplateWidget createEntity(PageTemplateWidget source) {
+        JpaPageTemplateWidget converted = null;
+        if (source != null) {
+            converted = manager.find(JpaPageTemplateWidget.class, source.getId());
+
+            if (converted == null) {
+                converted = new JpaPageTemplateWidget();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(PageTemplateWidget source, JpaPageTemplateWidget converted) {
+        converted.setEntityId(source.getId());
+        converted.setHideChrome(source.isHideChrome());
+        converted.setPageTemplateRegion(source.getPageTemplateRegion());
+        converted.setRenderSeq(source.getRenderSeq());
+        converted.setWidget(source.getWidget());
+        converted.setLocked(source.isLocked());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageUserConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageUserConverter.java
new file mode 100644
index 0000000..d5d00e8
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPageUserConverter.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPageUser;
+import org.apache.rave.portal.model.PageUser;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts a PageUser to a JpaPageUser
+ */
+@Component
+public class JpaPageUserConverter implements ModelConverter<PageUser, JpaPageUser> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<PageUser> getSourceType() {
+        return PageUser.class;
+    }
+
+    @Override
+    public JpaPageUser convert(PageUser source) {
+        return source instanceof JpaPageUser ? (JpaPageUser) source : createEntity(source);
+    }
+
+    private JpaPageUser createEntity(PageUser source) {
+        JpaPageUser converted = null;
+        if (source != null) {
+            converted = manager.find(JpaPageUser.class, source.getId());
+            if (converted == null) {
+                converted = new JpaPageUser();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(PageUser source, JpaPageUser converted) {
+        converted.setEntityId(source.getId());
+        converted.setId(source.getId());
+        converted.setPage(source.getPage());
+        converted.setPageStatus(source.getPageStatus());
+        converted.setRenderSequence(source.getRenderSequence());
+        converted.setUser(source.getUser());
+        converted.setEditor(source.isEditor());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java
new file mode 100644
index 0000000..742d93a
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonConverter.java
@@ -0,0 +1,64 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPerson;
+import org.apache.rave.portal.model.Person;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+/**
+ * Converts from a {@link org.apache.rave.portal.model.Person} to a {@link org.apache.rave.portal.model.JpaPerson}
+ */
+@Component
+public class JpaPersonConverter implements ModelConverter<Person, JpaPerson> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public JpaPerson convert(Person source) {
+        return source instanceof JpaPerson ? (JpaPerson) source : createEntity(source);
+    }
+
+    @Override
+    public Class<Person> getSourceType() {
+        return Person.class;
+    }
+
+    private JpaPerson createEntity(Person source) {
+        JpaPerson converted = null;
+        if (source != null) {
+            TypedQuery<JpaPerson> query = manager.createNamedQuery(JpaPerson.FIND_BY_USERNAME, JpaPerson.class);
+            query.setParameter(JpaPerson.USERNAME_PARAM, source.getUsername());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaPerson();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Person source, JpaPerson converted) {
+        converted.setUsername(source.getUsername());
+        converted.setEmail(source.getEmail());
+        converted.setDisplayName(source.getDisplayName());
+        converted.setAdditionalName(source.getUsername());
+        converted.setFamilyName(source.getFamilyName());
+        converted.setGivenName(source.getGivenName());
+        converted.setHonorificPrefix(source.getHonorificPrefix());
+        converted.setHonorificSuffix(source.getHonorificSuffix());
+        converted.setPreferredName(source.getPreferredName());
+        converted.setAboutMe(source.getAboutMe());
+        converted.setStatus(source.getStatus());
+        converted.setAddresses(source.getAddresses());
+        converted.setOrganizations(source.getOrganizations());
+        converted.setProperties(source.getProperties());
+        converted.setFriends(source.getFriends());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonPropertyConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonPropertyConverter.java
new file mode 100644
index 0000000..1ce0aa2
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPersonPropertyConverter.java
@@ -0,0 +1,41 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaPersonProperty;
+import org.apache.rave.portal.model.PersonProperty;
+import org.springframework.stereotype.Component;
+
+/**
+ * Converts an Address to a JpaAddress
+ */
+@Component
+public class JpaPersonPropertyConverter implements ModelConverter<PersonProperty, JpaPersonProperty> {
+
+    @Override
+    public Class<PersonProperty> getSourceType() {
+        return PersonProperty.class;
+    }
+
+    @Override
+    public JpaPersonProperty convert(PersonProperty source) {
+        return source instanceof JpaPersonProperty ? (JpaPersonProperty) source : createEntity(source);
+    }
+
+    private JpaPersonProperty createEntity(PersonProperty source) {
+        JpaPersonProperty converted = null;
+        if (source != null) {
+            converted  = new JpaPersonProperty();
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(PersonProperty source, JpaPersonProperty converted) {
+        converted.setId(source.getId());
+        converted.setQualifier(source.getQualifier());
+        converted.setPrimary(source.getPrimary());
+        converted.setType(source.getType());
+        converted.setValue(source.getValue());
+        converted.setExtendedValue(source.getExtendedValue());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPortalPreferenceConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPortalPreferenceConverter.java
new file mode 100644
index 0000000..b502500
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaPortalPreferenceConverter.java
@@ -0,0 +1,52 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.JpaPortalPreference;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+/**
+ * Converts an PortalPreference JpaPortalPreference
+ */
+@Component
+public class JpaPortalPreferenceConverter implements ModelConverter<PortalPreference, JpaPortalPreference> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<PortalPreference> getSourceType() {
+        return PortalPreference.class;
+    }
+
+    @Override
+    public JpaPortalPreference convert(PortalPreference source) {
+        return source instanceof JpaPortalPreference ? (JpaPortalPreference) source : createEntity(source);
+    }
+
+    private JpaPortalPreference createEntity(PortalPreference source) {
+        JpaPortalPreference converted = null;
+        if (source != null) {
+            TypedQuery<JpaPortalPreference> query = manager.createNamedQuery(JpaPortalPreference.GET_BY_KEY, JpaPortalPreference.class);
+            query.setParameter(JpaPortalPreference.PARAM_KEY, source.getKey());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaPortalPreference();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(PortalPreference source, JpaPortalPreference converted) {
+        converted.setKey(source.getKey());
+        converted.setValues(source.getValues());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionConverter.java
new file mode 100644
index 0000000..b11aeed
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionConverter.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaRegion;
+import org.apache.rave.portal.model.Region;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+@Component
+public class JpaRegionConverter implements ModelConverter<Region, JpaRegion> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Region> getSourceType() {
+        return Region.class;
+    }
+
+    @Override
+    public JpaRegion convert(Region source) {
+        return source instanceof JpaRegion ? (JpaRegion) source : createEntity(source);
+    }
+
+    private JpaRegion createEntity(Region source) {
+        JpaRegion converted = null;
+        if (source != null) {
+            TypedQuery<JpaRegion> query = manager.createNamedQuery(JpaRegion.FIND_BY_ENTITY_ID, JpaRegion.class);
+            query.setParameter(JpaRegion.ENTITY_ID_PARAM, source.getId());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaRegion();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Region source, JpaRegion converted) {
+        converted.setId(source.getId());
+        converted.setLocked(source.isLocked());
+        converted.setPage(source.getPage());
+        converted.setRegionWidgets(source.getRegionWidgets());
+        converted.setRenderOrder(source.getRenderOrder());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetConverter.java
new file mode 100644
index 0000000..b5f31e1
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetConverter.java
@@ -0,0 +1,55 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaRegionWidget;
+import org.apache.rave.portal.model.RegionWidget;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+@Component
+public class JpaRegionWidgetConverter implements ModelConverter<RegionWidget, JpaRegionWidget> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<RegionWidget> getSourceType() {
+        return RegionWidget.class;
+    }
+
+    @Override
+    public JpaRegionWidget convert(RegionWidget source) {
+        return source instanceof JpaRegionWidget ? (JpaRegionWidget) source : createEntity(source);
+    }
+
+    private JpaRegionWidget createEntity(RegionWidget source) {
+        JpaRegionWidget converted = null;
+        if (source != null) {
+            TypedQuery<JpaRegionWidget> query = manager.createNamedQuery(JpaRegionWidget.FIND_BY_ID, JpaRegionWidget.class);
+            query.setParameter(JpaRegionWidget.PARAM_WIDGET_ID, source.getId());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaRegionWidget();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(RegionWidget source, JpaRegionWidget converted) {
+        converted.setId(source.getId());
+        converted.setLocked(source.isLocked());
+        converted.setCollapsed(source.isCollapsed());
+        converted.setHideChrome(source.isHideChrome());
+        converted.setPreferences(source.getPreferences());
+        converted.setRegion(source.getRegion());
+        converted.setRenderPosition(source.getRenderPosition());
+        converted.setWidget(source.getWidget());
+        converted.setRenderOrder(source.getRenderOrder());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetPreferenceConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetPreferenceConverter.java
new file mode 100644
index 0000000..8cd4559
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetPreferenceConverter.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaRegionWidgetPreference;
+import org.apache.rave.portal.model.RegionWidgetPreference;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+@Component
+public class JpaRegionWidgetPreferenceConverter implements ModelConverter<RegionWidgetPreference, JpaRegionWidgetPreference> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<RegionWidgetPreference> getSourceType() {
+        return RegionWidgetPreference.class;
+    }
+
+    @Override
+    public JpaRegionWidgetPreference convert(RegionWidgetPreference source) {
+        return source instanceof JpaRegionWidgetPreference ? (JpaRegionWidgetPreference) source : createEntity(source);
+    }
+
+    private JpaRegionWidgetPreference createEntity(RegionWidgetPreference source) {
+        JpaRegionWidgetPreference converted = null;
+        if (source != null) {
+            TypedQuery<JpaRegionWidgetPreference> query = manager.createNamedQuery(JpaRegionWidgetPreference.FIND_BY_REGION_WIDGET_AND_NAME, JpaRegionWidgetPreference.class);
+            query.setParameter(JpaRegionWidgetPreference.NAME_PARAM, source.getName());
+            query.setParameter(JpaRegionWidgetPreference.REGION_WIDGET_ID, source.getRegionWidgetId());
+            converted = getSingleResult(query.getResultList());
+
+            if (converted == null) {
+                converted = new JpaRegionWidgetPreference();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(RegionWidgetPreference source, JpaRegionWidgetPreference converted) {
+        converted.setName(source.getName());
+        converted.setRegionWidgetId(source.getRegionWidgetId());
+        converted.setValue(source.getValue());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaTagConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaTagConverter.java
new file mode 100644
index 0000000..100c83d
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaTagConverter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.persistence.jpa.util.JpaUtil;
+import org.apache.rave.portal.model.JpaTag;
+import org.apache.rave.portal.model.Tag;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+/**
+ * Converts from a {@link org.apache.rave.portal.model.Tag} to a {@link org.apache.rave.portal.model.JpaTag}
+ */
+@Component
+public class JpaTagConverter implements ModelConverter<Tag, JpaTag> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<Tag> getSourceType() {
+        return Tag.class;
+    }
+
+    @Override
+    public JpaTag convert(Tag source) {
+        return source instanceof JpaTag ? (JpaTag)source : createEntity(source);
+    }
+
+    private JpaTag createEntity(Tag source) {
+        JpaTag convertedTag;
+        TypedQuery<JpaTag> query = manager.createNamedQuery(JpaTag.FIND_BY_KEYWORD, JpaTag.class);
+        query.setParameter(JpaTag.KEYWORD_PARAM, source.getKeyword());
+        convertedTag = JpaUtil.getSingleResult(query.getResultList());
+
+        if (convertedTag == null){
+            convertedTag = new JpaTag();
+        }
+        updateProperties(source, convertedTag);
+        return convertedTag;
+    }
+
+    private void updateProperties(Tag source, JpaTag jpaTag) {
+        jpaTag.setKeyword(source.getKeyword());
+        jpaTag.setWidgets(source.getWidgets());
+    }
+
+
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaUserConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaUserConverter.java
new file mode 100644
index 0000000..9476044
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaUserConverter.java
@@ -0,0 +1,77 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.JpaUser;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.AuthorityImpl;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts from a {@link org.apache.rave.portal.model.User} to a {@link org.apache.rave.portal.model.JpaUser}
+ */
+@Component
+public class JpaUserConverter implements ModelConverter<User, JpaUser> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public JpaUser convert(User source) {
+        return source instanceof JpaUser ? (JpaUser) source : createEntity(source);
+    }
+
+    @Override
+    public Class<User> getSourceType() {
+        return User.class;
+    }
+
+    private JpaUser createEntity(User source) {
+        JpaUser converted = null;
+        if (source != null) {
+            converted = new JpaUser();
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(User source, JpaUser converted) {
+        converted.setEntityId(source.getId());
+        converted.setUsername(source.getUsername());
+        converted.setEmail(source.getEmail());
+        converted.setDisplayName(source.getDisplayName());
+        converted.setAdditionalName(source.getUsername());
+        converted.setFamilyName(source.getFamilyName());
+        converted.setGivenName(source.getGivenName());
+        converted.setHonorificPrefix(source.getHonorificPrefix());
+        converted.setHonorificSuffix(source.getHonorificSuffix());
+        converted.setPreferredName(source.getPreferredName());
+        converted.setAboutMe(source.getAboutMe());
+        converted.setStatus(source.getStatus());
+        converted.setAddresses(source.getAddresses());
+        converted.setOrganizations(source.getOrganizations());
+        converted.setProperties(source.getProperties());
+        converted.setFriends(source.getFriends());
+        converted.setPassword(source.getPassword());
+        converted.setConfirmPassword(source.getConfirmPassword());
+        converted.setDefaultPageLayout(source.getDefaultPageLayout());
+        converted.setDefaultPageLayoutCode(source.getDefaultPageLayoutCode());
+        converted.setEnabled(source.isEnabled());
+        converted.setExpired(source.isExpired());
+        converted.setLocked(source.isLocked());
+        converted.setOpenId(source.getOpenId());
+        converted.setForgotPasswordHash(source.getForgotPasswordHash());
+        converted.setForgotPasswordTime(source.getForgotPasswordTime());
+        updateAuthorities(source, converted);
+    }
+
+    private void updateAuthorities(User source, JpaUser converted) {
+        converted.getAuthorities().clear();
+        for(GrantedAuthority grantedAuthority : source.getAuthorities()) {
+            converted.addAuthority(grantedAuthority instanceof Authority ? (Authority)grantedAuthority : new AuthorityImpl(grantedAuthority));
+        }
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetCommentConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetCommentConverter.java
new file mode 100644
index 0000000..0202501
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetCommentConverter.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaWidgetComment;
+import org.apache.rave.portal.model.WidgetComment;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts a WidgetComment to a JpaWidgetComment
+ */
+@Component
+public class JpaWidgetCommentConverter implements ModelConverter<WidgetComment, JpaWidgetComment> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<WidgetComment> getSourceType() {
+        return WidgetComment.class;
+    }
+
+    @Override
+    public JpaWidgetComment convert(WidgetComment source) {
+        return source instanceof JpaWidgetComment ? (JpaWidgetComment) source : createEntity(source);
+    }
+
+    private JpaWidgetComment createEntity(WidgetComment source) {
+        JpaWidgetComment converted = null;
+        if (source != null) {
+            converted = manager.find(JpaWidgetComment.class, source.getId());
+
+            if (converted == null) {
+                converted = new JpaWidgetComment();
+            }
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(WidgetComment source, JpaWidgetComment converted) {
+        converted.setEntityId(source.getId());
+        converted.setId(source.getId());
+        converted.setCreatedDate(source.getCreatedDate());
+        converted.setLastModifiedDate(source.getLastModifiedDate());
+        converted.setText(source.getText());
+        converted.setUser(source.getUser());
+        converted.setWidgetId(source.getWidgetId());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetConverter.java
new file mode 100644
index 0000000..93f895e
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetConverter.java
@@ -0,0 +1,59 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaWidget;
+import org.apache.rave.portal.model.Widget;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+/**
+ * Converts from a {@link org.apache.rave.portal.model.Widget} to a {@link org.apache.rave.portal.model.JpaWidget}
+ */
+@Component
+public class JpaWidgetConverter implements ModelConverter<Widget, JpaWidget> {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public JpaWidget convert(Widget source) {
+        return source instanceof JpaWidget ? (JpaWidget) source : createEntity(source);
+    }
+
+    @Override
+    public Class<Widget> getSourceType() {
+        return Widget.class;
+    }
+
+    private JpaWidget createEntity(Widget source) {
+        JpaWidget converted = null;
+        if (source != null) {
+            converted = new JpaWidget();
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(Widget source, JpaWidget converted) {
+        converted.setEntityId(source.getId());
+        converted.setUrl(source.getUrl());
+        converted.setType(source.getType());
+        converted.setTitle(source.getTitle());
+        converted.setTitleUrl(source.getTitleUrl());
+        converted.setUrl(source.getUrl());
+        converted.setThumbnailUrl(source.getThumbnailUrl());
+        converted.setScreenshotUrl(source.getScreenshotUrl());
+        converted.setAuthor(source.getAuthor());
+        converted.setAuthorEmail(source.getAuthorEmail());
+        converted.setDescription(source.getDescription());
+        converted.setWidgetStatus(source.getWidgetStatus());
+        converted.setComments(source.getComments());
+        converted.setOwner(source.getOwner());
+        converted.setDisableRendering(source.isDisableRendering());
+        converted.setRatings(source.getRatings());
+        converted.setTags(source.getTags());
+        converted.setCategories(source.getCategories());
+        converted.setFeatured(source.isFeatured());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetRatingConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetRatingConverter.java
new file mode 100644
index 0000000..1370e8c
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetRatingConverter.java
@@ -0,0 +1,39 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.JpaWidgetRating;
+import org.apache.rave.portal.model.WidgetRating;
+import org.springframework.stereotype.Component;
+
+/**
+ * Converts a WidgetRating to a JpaWidgetRating
+ */
+@Component
+public class JpaWidgetRatingConverter implements ModelConverter<WidgetRating, JpaWidgetRating> {
+
+    @Override
+    public Class<WidgetRating> getSourceType() {
+        return WidgetRating.class;
+    }
+
+    @Override
+    public JpaWidgetRating convert(WidgetRating source) {
+        return source instanceof JpaWidgetRating ? (JpaWidgetRating) source : createEntity(source);
+    }
+
+    private JpaWidgetRating createEntity(WidgetRating source) {
+        JpaWidgetRating converted = null;
+        if(source != null) {
+            converted = new JpaWidgetRating();
+            updateProperties(source, converted);
+        }
+        return converted;
+    }
+
+    private void updateProperties(WidgetRating source, JpaWidgetRating converted) {
+        converted.setId(source.getId());
+        converted.setScore(source.getScore());
+        converted.setUserId(source.getUserId());
+        converted.setWidgetId(source.getWidgetId());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetTagConverter.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetTagConverter.java
new file mode 100644
index 0000000..89181ac
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/model/conversion/JpaWidgetTagConverter.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * 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.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.persistence.jpa.util.JpaUtil;
+import org.apache.rave.portal.model.JpaWidgetTag;
+import org.apache.rave.portal.model.WidgetTag;
+import org.springframework.stereotype.Component;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+/**
+ * Converts from a {@link org.apache.rave.portal.model.WidgetTag} to a {@link org.apache.rave.portal.model.JpaWidgetTag}
+ */
+@Component
+public class JpaWidgetTagConverter implements ModelConverter<WidgetTag, JpaWidgetTag> {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public Class<WidgetTag> getSourceType() {
+        return WidgetTag.class;
+    }
+
+    @Override
+    public JpaWidgetTag convert(WidgetTag source) {
+        return source instanceof JpaWidgetTag ? (JpaWidgetTag)source : createEntity(source);
+    }
+
+    private JpaWidgetTag createEntity(WidgetTag source) {
+        JpaWidgetTag convertedWidgetTag;
+        TypedQuery<JpaWidgetTag> query = manager.createNamedQuery(JpaWidgetTag.FIND_BY_WIDGET_AND_KEYWORD, JpaWidgetTag.class);
+        query.setParameter(JpaWidgetTag.WIDGET_ID_PARAM, source.getWidgetId());
+        query.setParameter(JpaWidgetTag.TAG_KEYWORD_PARAM, source.getTag().getKeyword());
+        convertedWidgetTag = JpaUtil.getSingleResult(query.getResultList());
+
+        if (convertedWidgetTag == null){
+            convertedWidgetTag = new JpaWidgetTag();
+        }
+        updateProperties(source, convertedWidgetTag);
+        return convertedWidgetTag;
+    }
+
+    private void updateProperties(WidgetTag source, JpaWidgetTag convertedWidgetTag) {
+        convertedWidgetTag.setCreatedDate(source.getCreatedDate());
+        convertedWidgetTag.setTag(source.getTag());
+        convertedWidgetTag.setUser(source.getUser());
+        convertedWidgetTag.setWidgetId(source.getWidgetId());
+    }
+}
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/JpaApplicationDataRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaApplicationDataRepository.java
similarity index 70%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/JpaApplicationDataRepository.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaApplicationDataRepository.java
index 3b57f25..34b1cea 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/JpaApplicationDataRepository.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaApplicationDataRepository.java
@@ -16,32 +16,62 @@
  * specific language governing permissions and limitations

  * under the License.

  */

-package org.apache.rave.opensocial.repository.impl;

+package org.apache.rave.portal.repository.impl;

 

 import org.apache.commons.lang.StringUtils;

 import org.apache.rave.exception.DataSerializationException;

-import org.apache.rave.opensocial.model.ApplicationData;

-import org.apache.rave.opensocial.repository.ApplicationDataRepository;

-import org.apache.rave.persistence.jpa.AbstractJpaRepository;

+import org.apache.rave.portal.model.ApplicationData;

+import org.apache.rave.portal.model.JpaApplicationData;

+import org.apache.rave.portal.model.conversion.JpaApplicationDataConverter;

+import org.apache.rave.portal.repository.ApplicationDataRepository;

+import org.apache.rave.util.CollectionUtils;

 import org.json.JSONException;

 import org.json.JSONObject;

+import org.springframework.beans.factory.annotation.Autowired;

 import org.springframework.stereotype.Repository;

 import org.springframework.transaction.annotation.Transactional;

 

-import javax.persistence.Column;

-import javax.persistence.Entity;

-import javax.persistence.Lob;

-import javax.persistence.TypedQuery;

+import javax.persistence.*;

 import java.util.*;

 

 import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;

+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;

 

 @Repository

-public class JpaApplicationDataRepository extends AbstractJpaRepository<ApplicationData>

-        implements ApplicationDataRepository {

+public class JpaApplicationDataRepository implements ApplicationDataRepository {

 

-    public JpaApplicationDataRepository() {

-        super(JpaSerializableApplicationData.class);

+    @PersistenceContext

+    private EntityManager manager;

+

+    @Autowired

+    private JpaApplicationDataConverter converter;

+

+    @Override

+    public Class<? extends ApplicationData> getType() {

+        return JpaApplicationData.class;

+    }

+

+    @Override

+    public ApplicationData get(long id) {

+        JpaSerializableApplicationData applicationData = (JpaSerializableApplicationData) manager.find(JpaApplicationData.class, id);

+        if (applicationData != null) {

+            applicationData.deserializeData();

+        }

+        return applicationData;

+    }

+

+    @Override

+    @Transactional

+    public JpaApplicationData save(ApplicationData item) {

+        JpaApplicationData jpaAppData = converter.convert(item);

+        JpaSerializableApplicationData jpaSerializableApplicationData = getJpaSerializableApplicationData(jpaAppData);

+        jpaSerializableApplicationData.serializeData();

+        return saveOrUpdate(jpaSerializableApplicationData.getEntityId(), manager, jpaSerializableApplicationData);

+    }

+

+    @Override

+    public void delete(ApplicationData item) {

+        manager.remove(item instanceof JpaApplicationData ? item : get(item.getId()));

     }

 

     @Override

@@ -56,23 +86,23 @@
             return data;

         }

 

-        TypedQuery<JpaSerializableApplicationData> query = manager.createNamedQuery(ApplicationData.FIND_BY_USER_IDS_AND_APP_ID,

+        TypedQuery<JpaSerializableApplicationData> query = manager.createNamedQuery(JpaApplicationData.FIND_BY_USER_IDS_AND_APP_ID,

                 JpaSerializableApplicationData.class);

-        query.setParameter(ApplicationData.USER_IDS_PARAM, userIds);

-        query.setParameter(ApplicationData.APP_URL_PARAM, appId);

+        query.setParameter(JpaApplicationData.USER_IDS_PARAM, userIds);

+        query.setParameter(JpaApplicationData.APP_URL_PARAM, appId);

         List<JpaSerializableApplicationData> results = query.getResultList();

         for (JpaSerializableApplicationData applicationData : results) {

             applicationData.deserializeData();

         }

-        return new ArrayList<ApplicationData>(results);

+        return CollectionUtils.<ApplicationData>toBaseTypedList(results);

     }

 

     @Override

-    public ApplicationData getApplicationData(String personId, String appId) {

-        TypedQuery<JpaSerializableApplicationData> query = manager.createNamedQuery(ApplicationData.FIND_BY_USER_ID_AND_APP_ID,

+    public JpaApplicationData getApplicationData(String personId, String appId) {

+        TypedQuery<JpaSerializableApplicationData> query = manager.createNamedQuery(JpaApplicationData.FIND_BY_USER_ID_AND_APP_ID,

                 JpaSerializableApplicationData.class);

-        query.setParameter(ApplicationData.USER_ID_PARAM, personId);

-        query.setParameter(ApplicationData.APP_URL_PARAM, appId);

+        query.setParameter(JpaApplicationData.USER_ID_PARAM, personId);

+        query.setParameter(JpaApplicationData.APP_URL_PARAM, appId);

         JpaSerializableApplicationData applicationData = getSingleResult(query.getResultList());

         if (applicationData != null) {

             applicationData.deserializeData();

@@ -80,24 +110,7 @@
         return applicationData;

     }

 

-    @Override

-    public ApplicationData get(long id) {

-        JpaSerializableApplicationData applicationData = (JpaSerializableApplicationData) super.get(id);

-        if (applicationData != null) {

-            applicationData.deserializeData();

-        }

-        return applicationData;

-    }

-

-    @Override

-    @Transactional

-    public ApplicationData save(ApplicationData applicationData) {

-        JpaSerializableApplicationData jpaSerializableApplicationData = getJpaSerializableApplicationData(applicationData);

-        jpaSerializableApplicationData.serializeData();

-        return super.save(jpaSerializableApplicationData);

-    }

-

-    private JpaSerializableApplicationData getJpaSerializableApplicationData(ApplicationData applicationData) {

+    private JpaSerializableApplicationData getJpaSerializableApplicationData(JpaApplicationData applicationData) {

         if (applicationData instanceof JpaSerializableApplicationData) {

             return (JpaSerializableApplicationData) applicationData;

         }

@@ -114,7 +127,7 @@
      * uses this model for the actual persistence to the database.

      */

     @Entity

-    public static class JpaSerializableApplicationData extends ApplicationData {

+    public static class JpaSerializableApplicationData extends JpaApplicationData {

         @Lob

         @Column(name = "serialized_data")

         private String serializedData;

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepository.java
new file mode 100644
index 0000000..03ad2ec
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepository.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.JpaAuthority;
+import org.apache.rave.portal.model.conversion.JpaAuthorityConverter;
+import org.apache.rave.portal.repository.AuthorityRepository;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+/**
+ * JPA implementation for {@link org.apache.rave.portal.repository.AuthorityRepository}
+ */
+@Repository
+public class JpaAuthorityRepository implements AuthorityRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaAuthorityConverter converter;
+
+
+    @Override
+    public Authority getByAuthority(String authorityName) {
+        TypedQuery<JpaAuthority> query = manager.createNamedQuery(JpaAuthority.GET_BY_AUTHORITY_NAME, JpaAuthority.class);
+        query.setParameter(JpaAuthority.PARAM_AUTHORITY_NAME, authorityName);
+        return getSingleResult(query.getResultList());
+    }
+
+    @Override
+    public List<Authority> getAll() {
+        TypedQuery<JpaAuthority> query = manager.createNamedQuery(JpaAuthority.GET_ALL, JpaAuthority.class);
+        return CollectionUtils.<Authority>toBaseTypedList(query.getResultList());
+    }
+    
+    @Override
+    public List<Authority> getAllDefault() {
+        TypedQuery<JpaAuthority> query = manager.createNamedQuery(JpaAuthority.GET_ALL_DEFAULT, JpaAuthority.class);
+        return CollectionUtils.<Authority>toBaseTypedList(query.getResultList());
+    }    
+
+    @Override
+    public int getCountAll() {
+        Query query = manager.createNamedQuery(JpaAuthority.COUNT_ALL);
+        Number countResult = (Number) query.getSingleResult();
+        return countResult.intValue();
+    }
+
+    @Override
+    public Class<? extends Authority> getType() {
+        return JpaAuthority.class;
+    }
+
+    @Override
+    public Authority get(long id) {
+        return manager.find(JpaAuthority.class, id);
+    }
+
+    @Override
+    public Authority save(Authority item) {
+        JpaAuthority authority = converter.convert(item);
+        return saveOrUpdate(authority.getEntityId(), manager, authority);
+    }
+
+    @Override
+    public void delete(Authority item) {
+        manager.remove(converter.convert(item));
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaCategoryRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaCategoryRepository.java
new file mode 100644
index 0000000..d364b89
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaCategoryRepository.java
@@ -0,0 +1,100 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.repository.impl;

+

+import org.apache.rave.portal.model.Category;

+import org.apache.rave.portal.model.JpaCategory;

+import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.conversion.JpaCategoryConverter;

+import org.apache.rave.portal.repository.CategoryRepository;

+import org.apache.rave.util.CollectionUtils;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.stereotype.Repository;

+

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

+import java.util.List;

+

+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;

+

+/**

+ * JPA implementation for {@link org.apache.rave.portal.repository.CategoryRepository}

+ */

+@Repository

+public class JpaCategoryRepository implements CategoryRepository {

+

+    @PersistenceContext

+    private EntityManager manager;

+

+    @Autowired

+    private JpaCategoryConverter categoryConverter;

+

+    @Override

+    public Class<? extends Category> getType() {

+        return JpaCategory.class;

+    }

+

+    @Override

+    public Category get(long id) {

+        return manager.find(JpaCategory.class, id);

+    }

+

+    @Override

+    public Category save(Category item) {

+        JpaCategory category = categoryConverter.convert(item);

+        return saveOrUpdate(category.getEntityId(), manager, category);

+    }

+

+    @Override

+    public void delete(Category item) {

+        manager.remove(item instanceof JpaCategory ? item : get(item.getId()));

+    }

+

+    @Override

+    public List<Category> getAll() {

+        List<JpaCategory> resultList = manager.createNamedQuery(JpaCategory.GET_ALL, JpaCategory.class).getResultList();

+        return CollectionUtils.<Category>toBaseTypedList(resultList);

+    }

+    

+    @Override

+    public int removeFromCreatedOrModifiedFields(long userId) {

+       List<Category> categories = getAll();

+       int numRecordsChanged = 0;

+       for (Category category : categories) {

+           boolean changed = false;

+           User createdUser = category.getCreatedUser();

+           User lastModifiedUser = category.getLastModifiedUser();

+           if (createdUser != null && userId == createdUser.getId()) {

+               category.setCreatedUser(null);

+               changed = true;

+               }

+           if (lastModifiedUser != null && userId == lastModifiedUser.getId()) {

+               category.setLastModifiedUser(null);

+               changed = true;

+               }

+           if (changed) {

+               numRecordsChanged++;

+               save(category);

+               }

+           }

+       return numRecordsChanged;

+

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaOAuthConsumerStoreRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaOAuthConsumerStoreRepository.java
new file mode 100644
index 0000000..edd6631
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaOAuthConsumerStoreRepository.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaOAuthConsumerStore;
+import org.apache.rave.portal.model.OAuthConsumerStore;
+import org.apache.rave.portal.model.conversion.JpaOAuthConsumerStoreConverter;
+import org.apache.rave.portal.repository.OAuthConsumerStoreRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+/**
+ * JPA implementation for {@link OAuthConsumerStoreRepository}
+ */
+@Repository
+public class JpaOAuthConsumerStoreRepository implements OAuthConsumerStoreRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaOAuthConsumerStoreConverter converter;
+
+    @Override
+    public Class<? extends OAuthConsumerStore> getType() {
+        return JpaOAuthConsumerStore.class;
+    }
+
+    @Override
+    public OAuthConsumerStore get(long id) {
+        return manager.find(JpaOAuthConsumerStore.class, id);
+    }
+
+    @Override
+    public OAuthConsumerStore save(OAuthConsumerStore item) {
+        JpaOAuthConsumerStore jpaItem = converter.convert(item);
+        return saveOrUpdate(jpaItem.getEntityId(), manager, jpaItem);
+    }
+
+    @Override
+    public void delete(OAuthConsumerStore item) {
+        manager.remove(converter.convert(item));
+    }
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName) {
+        TypedQuery<JpaOAuthConsumerStore> query = manager.createNamedQuery(
+                JpaOAuthConsumerStore.FIND_BY_URI_AND_SERVICE_NAME, JpaOAuthConsumerStore.class);
+        query.setParameter(JpaOAuthConsumerStore.GADGET_URI_PARAM, gadgetUri);
+        query.setParameter(JpaOAuthConsumerStore.SERVICE_NAME_PARAM, serviceName);
+        return getSingleResult(query.getResultList());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaOAuthTokenInfoRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaOAuthTokenInfoRepository.java
new file mode 100644
index 0000000..cec19e2
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaOAuthTokenInfoRepository.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaOAuthTokenInfo;
+import org.apache.rave.portal.model.OAuthTokenInfo;
+import org.apache.rave.portal.model.conversion.JpaOAuthTokenInfoConverter;
+import org.apache.rave.portal.repository.OAuthTokenInfoRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+/**
+ * JPA implementation for {@link OAuthTokenInfoRepository}
+ */
+@Repository
+public class JpaOAuthTokenInfoRepository implements OAuthTokenInfoRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaOAuthTokenInfoConverter converter;
+
+    @Override
+    public Class<? extends OAuthTokenInfo> getType() {
+        return JpaOAuthTokenInfo.class;
+    }
+
+    @Override
+    public OAuthTokenInfo get(long id) {
+        return manager.find(JpaOAuthTokenInfo.class, id);
+    }
+
+    @Override
+    public OAuthTokenInfo save(OAuthTokenInfo item) {
+        JpaOAuthTokenInfo jpaItem = converter.convert(item);
+        return saveOrUpdate(jpaItem.getEntityId(), manager, jpaItem);
+    }
+
+    @Override
+    public void delete(OAuthTokenInfo item) {
+        manager.remove(converter.convert(item));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
+                                             String tokenName, String serviceName) {
+        TypedQuery<JpaOAuthTokenInfo> query = manager.createNamedQuery(JpaOAuthTokenInfo.FIND_OAUTH_TOKEN_INFO, JpaOAuthTokenInfo.class);
+        query.setParameter(JpaOAuthTokenInfo.USER_ID_PARAM, userId);
+        query.setParameter(JpaOAuthTokenInfo.APP_URL_PARAM, appUrl);
+        query.setParameter(JpaOAuthTokenInfo.MODULE_ID_PARAM, moduleId);
+        query.setParameter(JpaOAuthTokenInfo.TOKEN_NAME_PARAM, tokenName);
+        query.setParameter(JpaOAuthTokenInfo.SERVICE_NAME_PARAM, serviceName);
+        return getSingleResult(query.getResultList());
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepository.java
new file mode 100644
index 0000000..d0ffba5
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepository.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaPageLayout;
+import org.apache.rave.portal.model.PageLayout;
+import org.apache.rave.portal.model.conversion.JpaPageLayoutConverter;
+import org.apache.rave.portal.repository.PageLayoutRepository;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+
+/**
+ */
+@Repository
+public class JpaPageLayoutRepository implements PageLayoutRepository{
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaPageLayoutConverter converter;
+
+    @Override
+    public JpaPageLayout getByPageLayoutCode(String codename){
+        TypedQuery<JpaPageLayout>query = manager.createNamedQuery(JpaPageLayout.PAGELAYOUT_GET_BY_LAYOUT_CODE,JpaPageLayout.class);
+        query.setParameter("code",codename);
+        return getSingleResult(query.getResultList());
+    }
+
+    @Override
+    public List<PageLayout> getAll() {
+        return CollectionUtils.<PageLayout>toBaseTypedList(manager.createNamedQuery(JpaPageLayout.PAGELAYOUT_GET_ALL, JpaPageLayout.class).getResultList());
+    }
+
+    @Override
+    public List<PageLayout> getAllUserSelectable() {
+        return CollectionUtils.<PageLayout>toBaseTypedList(manager.createNamedQuery(JpaPageLayout.PAGELAYOUT_GET_ALL_USER_SELECTABLE, JpaPageLayout.class).getResultList());
+    }
+
+    @Override
+    public Class<? extends PageLayout> getType() {
+        return JpaPageLayout.class;
+    }
+
+    @Override
+    public PageLayout get(long id) {
+        return manager.find(JpaPageLayout.class, id);
+    }
+
+    @Override
+    public PageLayout save(PageLayout item) {
+        JpaPageLayout layout = converter.convert(item);
+        return saveOrUpdate(layout.getEntityId(), manager, layout);
+    }
+
+    @Override
+    public void delete(PageLayout item) {
+        manager.remove(converter.convert(item));
+    }
+}
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
similarity index 60%
rename from rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
index 46c5634..3cb14b3 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageRepository.java
@@ -19,41 +19,81 @@
 

 package org.apache.rave.portal.repository.impl;

 

-import org.apache.rave.persistence.jpa.AbstractJpaRepository;

 import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.conversion.JpaConverter;

+import org.apache.rave.portal.model.conversion.JpaPageConverter;

 import org.apache.rave.portal.repository.PageRepository;

+import org.apache.rave.util.CollectionUtils;

+import org.springframework.beans.factory.annotation.Autowired;

 import org.springframework.stereotype.Repository;

 

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

 import javax.persistence.TypedQuery;

 import java.util.ArrayList;

 import java.util.List;

 

-@Repository

-public class JpaPageRepository extends AbstractJpaRepository<Page> implements PageRepository{

+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;

 

-    public JpaPageRepository() {

-        super(Page.class);

+@Repository

+public class JpaPageRepository implements PageRepository {

+

+    @PersistenceContext

+    private EntityManager manager;

+

+    @Autowired

+    private JpaPageConverter pageConverter;

+

+    @Override

+    public Class<? extends Page> getType() {

+        return JpaPage.class;

+    }

+

+    @Override

+    public Page get(long id) {

+        return manager.find(JpaPage.class, id);

+    }

+

+    @Override

+    public Page save(Page item) {

+        JpaPage page = pageConverter.convert(item);

+        return saveOrUpdate(page.getEntityId(), manager, page);

+    }

+

+    @Override

+    public void delete(Page item) {

+        JpaPage jpaPage = item instanceof JpaPage ? (JpaPage)item : (JpaPage)get(item.getId());

+        for(Page p : item.getSubPages()) {

+            delete(p);

+        }

+        //Must remove the page users from the page in order for OpenJpa to persist change

+        removePageUsers(jpaPage);

+        jpaPage.setParentPage(null);

+        manager.flush();

+        manager.remove(jpaPage);

     }

 

     @Override

     public List<Page> getAllPages(Long userId, PageType pageType) {

-        TypedQuery<Page> query = manager.createNamedQuery(PageUser.GET_BY_USER_ID_AND_PAGE_TYPE, Page.class);

+        TypedQuery<JpaPage> query = manager.createNamedQuery(JpaPageUser.GET_BY_USER_ID_AND_PAGE_TYPE, JpaPage.class);

         query.setParameter("userId", userId);

         query.setParameter("pageType", pageType);

-        return query.getResultList();

+        return CollectionUtils.<Page>toBaseTypedList(query.getResultList());

     }

 

     @Override

     public int deletePages(Long userId, PageType pageType) {

-        TypedQuery<Page> query = manager.createNamedQuery(Page.DELETE_BY_USER_ID_AND_PAGE_TYPE, Page.class);

-        query.setParameter("userId", userId);

-        query.setParameter("pageType", pageType);

-        return query.executeUpdate();

+        List<Page> pages = getAllPages(userId, pageType);

+        int pageCount = pages.size();

+        for(Page page : pages) {

+            delete(page);

+        }

+        return pageCount;

     }

 

     @Override

     public boolean hasPersonPage(long userId){

-        TypedQuery<Long> query = manager.createNamedQuery(Page.USER_HAS_PERSON_PAGE, Long.class);

+        TypedQuery<Long> query = manager.createNamedQuery(JpaPage.USER_HAS_PERSON_PAGE, Long.class);

         query.setParameter("userId", userId);

         query.setParameter("pageType", PageType.PERSON_PROFILE);

         return query.getSingleResult() > 0;

@@ -61,15 +101,15 @@
 

     @Override

     public List<PageUser> getPagesForUser(Long userId, PageType pageType) {

-        TypedQuery<PageUser> query = manager.createNamedQuery(PageUser.GET_PAGES_FOR_USER, PageUser.class);

+        TypedQuery<JpaPageUser> query = manager.createNamedQuery(JpaPageUser.GET_PAGES_FOR_USER, JpaPageUser.class);

         query.setParameter("userId", userId);

         query.setParameter("pageType", pageType);

-        return query.getResultList();

+        return CollectionUtils.<PageUser>toBaseTypedList(query.getResultList());

     }

 

     @Override

     public PageUser getSingleRecord(Long userId, Long pageId){

-        TypedQuery<PageUser> query = manager.createNamedQuery(PageUser.GET_SINGLE_RECORD, PageUser.class);

+        TypedQuery<JpaPageUser> query = manager.createNamedQuery(JpaPageUser.GET_SINGLE_RECORD, JpaPageUser.class);

         query.setParameter("userId", userId);

         query.setParameter("pageId", pageId);

         return query.getSingleResult();

@@ -77,8 +117,16 @@
 

     @Override

     public Page createPageForUser(User user, PageTemplate pt) {

-        Page personPageFromTemplate = convert(pt, user);

-        return personPageFromTemplate;

+        return convert(pt, user);

+    }

+

+    private void removePageUsers(JpaPage item) {

+        for(PageUser user : item.getMembers()) {

+            user.setPage(null);

+            user.setUser(null);

+            manager.flush();

+            manager.remove(user);

+        }

     }

 

     /**

@@ -89,11 +137,12 @@
      * @return Page

      */

     private Page convert(PageTemplate pt, User user) {

-        Page p = new Page();

+        JpaUser jpaUser = JpaConverter.getInstance().convert(user, User.class);

+        Page p = new JpaPage();

         p.setName(pt.getName());

         p.setPageType(pt.getPageType());

-        p.setOwner(user);

-        PageUser pageUser = new PageUser(p.getOwner(), p, pt.getRenderSequence());

+        p.setOwner(jpaUser);

+        PageUser pageUser = new JpaPageUser(jpaUser, p, pt.getRenderSequence());

         pageUser.setPageStatus(PageInvitationStatus.OWNER);

         pageUser.setEditor(true);

         List<PageUser> members = new ArrayList<PageUser>();

@@ -102,6 +151,9 @@
 

         p.setPageLayout(pt.getPageLayout());

         p.setRegions(convertRegions(pt.getPageTemplateRegions(), p));

+        //Workaround for an issue with OpenJPA where the transaction is applied in order of save methods and if

+        //the parent page doesn't have an id yet, it will throw a referential integrity error

+        p = save(p);

         p.setSubPages(convertPages(pt.getSubPageTemplates(), p));

         p = save(p);

         return p;

@@ -109,15 +161,15 @@
 

     /**

      * convertRegions: List of PageTemplateRegion, Page -> List of Regions

-     * Converts the Region Templates of the Page Template to Regions for the page

+     * Converts the JpaRegion Templates of the Page Template to Regions for the page

      * @param pageTemplateRegions List of PageTemplateRegion

      * @param page Page

-     * @return list of Region

+     * @return list of JpaRegion

      */

     private List<Region> convertRegions(List<PageTemplateRegion> pageTemplateRegions, Page page){

         List<Region> regions = new ArrayList<Region>();

         for (PageTemplateRegion ptr : pageTemplateRegions){

-            Region region = new Region();

+            JpaRegion region = new JpaRegion();

             region.setRenderOrder((int) ptr.getRenderSequence());

             region.setPage(page);

             region.setLocked(ptr.isLocked());

@@ -128,16 +180,16 @@
     }

 

     /**

-     * convertWidgets: List of PageTemplateWidget, Region -> List of RegionWidget

-     * Converts the Page Template Widgets to RegionWidgets for the given Region

+     * convertWidgets: List of PageTemplateWidget, JpaRegion -> List of RegionWidget

+     * Converts the Page Template Widgets to RegionWidgets for the given JpaRegion

      * @param pageTemplateWidgets List of PageTemplateWidget

-     * @param region Region

+     * @param region JpaRegion

      * @return List of RegionWidget

      */

-    private List<RegionWidget> convertWidgets(List<PageTemplateWidget> pageTemplateWidgets, Region region){

+    private List<RegionWidget> convertWidgets(List<PageTemplateWidget> pageTemplateWidgets, JpaRegion region){

         List<RegionWidget> widgets = new ArrayList<RegionWidget>();

         for (PageTemplateWidget ptw : pageTemplateWidgets){

-            RegionWidget regionWidget = new RegionWidget();

+            RegionWidget regionWidget = new JpaRegionWidget();

             regionWidget.setRegion(region);

             regionWidget.setCollapsed(false);

             regionWidget.setLocked(ptw.isLocked());

@@ -160,7 +212,7 @@
     private List<Page> convertPages(List<PageTemplate> pageTemplates, Page page){

         List<Page> pages = new ArrayList<Page>();

         for(PageTemplate pt : pageTemplates){

-            Page lPage = new Page();

+            Page lPage = new JpaPage();

             lPage.setName(pt.getName());

             lPage.setPageType(pt.getPageType());

             lPage.setOwner(page.getOwner());

@@ -169,13 +221,16 @@
             lPage.setRegions(convertRegions(pt.getPageTemplateRegions(), lPage));

 

             // create new pageUser tuple

-            PageUser pageUser = new PageUser(lPage.getOwner(), lPage, pt.getRenderSequence());

+            PageUser pageUser = new JpaPageUser((JpaUser)JpaConverter.getInstance().convert(lPage.getOwner(), User.class), lPage, pt.getRenderSequence());

             pageUser.setPageStatus(PageInvitationStatus.OWNER);

             pageUser.setEditor(true);

             List<PageUser> members = new ArrayList<PageUser>();

             members.add(pageUser);

             lPage.setMembers(members);

             // recursive call

+            //Workaround for an issue with OpenJPA where the transaction is applied in order of save methods and if

+            //the parent page doesn't have an id yet, it will throw a referential integrity error

+            lPage = save(lPage);

             lPage.setSubPages((pt.getSubPageTemplates() == null || pt.getSubPageTemplates().isEmpty()) ? null : convertPages(pt.getSubPageTemplates(), lPage));

             lPage = save(lPage);

             pages.add(lPage);

diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepository.java
similarity index 63%
rename from rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepository.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepository.java
index f1bd184..fab22a8 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepository.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepository.java
@@ -18,31 +18,33 @@
  */

 package org.apache.rave.portal.repository.impl;

 

-import org.apache.rave.persistence.jpa.AbstractJpaRepository;

+import org.apache.rave.portal.model.JpaPageTemplate;

 import org.apache.rave.portal.model.PageTemplate;

 import org.apache.rave.portal.model.PageType;

 import org.apache.rave.portal.repository.PageTemplateRepository;

+import org.apache.rave.util.CollectionUtils;

 import org.springframework.stereotype.Repository;

 

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

 import javax.persistence.TypedQuery;

 import java.util.List;

 

 @Repository

-public class JpaPageTemplateRepository extends AbstractJpaRepository<PageTemplate> implements PageTemplateRepository {

+public class JpaPageTemplateRepository implements PageTemplateRepository {

 

-    public JpaPageTemplateRepository() {

-        super(PageTemplate.class);

-    }

+    @PersistenceContext

+    private EntityManager manager;

 

     @Override

     public List<PageTemplate> getAll() {

-        TypedQuery<PageTemplate> query = manager.createNamedQuery(PageTemplate.PAGE_TEMPLATE_GET_ALL, PageTemplate.class);

-        return query.getResultList();

+        TypedQuery<JpaPageTemplate> query = manager.createNamedQuery(JpaPageTemplate.PAGE_TEMPLATE_GET_ALL, JpaPageTemplate.class);

+        return CollectionUtils.<PageTemplate>toBaseTypedList(query.getResultList());

     }

 

     @Override

-    public PageTemplate getDefaultPage(PageType pageType) {

-        TypedQuery<PageTemplate> query = manager.createNamedQuery(PageTemplate.PAGE_TEMPLATE_GET_DEFAULT_PAGE_BY_TYPE, PageTemplate.class);

+    public JpaPageTemplate getDefaultPage(PageType pageType) {

+        TypedQuery<JpaPageTemplate> query = manager.createNamedQuery(JpaPageTemplate.PAGE_TEMPLATE_GET_DEFAULT_PAGE_BY_TYPE, JpaPageTemplate.class);

         query.setParameter("pageType", pageType);

         return query.getSingleResult();

     }

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPersonRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPersonRepository.java
new file mode 100644
index 0000000..fa2693a
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPersonRepository.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.exception.NotSupportedException;
+import org.apache.rave.portal.model.JpaGroup;
+import org.apache.rave.portal.model.JpaPerson;
+import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.model.conversion.JpaPersonConverter;
+import org.apache.rave.portal.repository.PersonRepository;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+/**
+ *
+ */
+@Repository
+public class JpaPersonRepository implements PersonRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaPersonConverter personConverter;
+
+    @Override
+    public Person findByUsername(String username) {
+        TypedQuery<JpaPerson> query = manager.createNamedQuery(JpaPerson.FIND_BY_USERNAME, JpaPerson.class);
+        query.setParameter(JpaPerson.USERNAME_PARAM, username);
+        return getSingleResult(query.getResultList());
+    }
+
+    @Override
+    public List<Person> findAllConnectedPeople(String username) {
+        List<Person> connections = new ArrayList<Person>();
+        connections.addAll(findFriends(username));
+        TypedQuery<JpaPerson> members = manager.createNamedQuery(JpaPerson.FIND_BY_GROUP_MEMBERSHIP, JpaPerson.class);
+        members.setParameter(JpaPerson.USERNAME_PARAM, username);
+        CollectionUtils.addUniqueValues(CollectionUtils.<Person>toBaseTypedList(members.getResultList()), connections);
+        return connections;
+    }
+
+    @Override
+    public List<Person> findAllConnectedPeople(String username, String appId) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public List<Person> findAllConnectedPeopleWithFriend(String username, String friendUsername) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public List<Person> findFriends(String username) {
+        TypedQuery<JpaPerson> friends = manager.createNamedQuery(JpaPerson.FIND_FRIENDS_BY_USERNAME, JpaPerson.class);
+        friends.setParameter(JpaPerson.USERNAME_PARAM, username);
+        return CollectionUtils.<Person>toBaseTypedList(friends.getResultList());
+    }
+
+    @Override
+    public List<Person> findFriends(String username, String appId) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public List<Person> findFriendsWithFriend(String username, String friendUsername) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public List<Person> findByGroup(String groupId) {
+        TypedQuery<JpaGroup> query = manager.createNamedQuery(JpaGroup.FIND_BY_TITLE, JpaGroup.class);
+        query.setParameter(JpaGroup.GROUP_ID_PARAM, groupId);
+        JpaGroup result = getSingleResult(query.getResultList());
+        return result == null ? new ArrayList<Person>() : CollectionUtils.<Person>toBaseTypedList(result.getMembers());
+    }
+
+    @Override
+    public List<Person> findByGroup(String groupId, String appId) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public List<Person> findByGroupWithFriend(String groupId, String friendUsername) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public Class<? extends Person> getType() {
+        return JpaPerson.class;
+    }
+
+    @Override
+    public Person get(long id) {
+        return manager.find(JpaPerson.class, id);
+    }
+
+    @Override
+    public Person save(Person item) {
+        JpaPerson person = personConverter.convert(item);
+        return saveOrUpdate(person.getEntityId(), manager, person);
+    }
+
+    @Override
+    public void delete(Person item) {
+        manager.remove(item instanceof JpaPerson ? item : findByUsername(item.getUsername()));
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepository.java
new file mode 100644
index 0000000..0241c6b
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepository.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaPortalPreference;
+import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.conversion.JpaPortalPreferenceConverter;
+import org.apache.rave.portal.repository.PortalPreferenceRepository;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+/**
+ * JPA implementation for {@link PortalPreferenceRepository}
+ */
+@Repository
+public class JpaPortalPreferenceRepository implements PortalPreferenceRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaPortalPreferenceConverter converter;
+
+
+    @Override
+    public List<PortalPreference> getAll() {
+        final TypedQuery<JpaPortalPreference> query =
+                manager.createNamedQuery(JpaPortalPreference.GET_ALL, JpaPortalPreference.class);
+        return CollectionUtils.<PortalPreference>toBaseTypedList(query.getResultList());
+    }
+
+    @Override
+    public PortalPreference getByKey(String key) {
+        final TypedQuery<JpaPortalPreference> query =
+                manager.createNamedQuery(JpaPortalPreference.GET_BY_KEY, JpaPortalPreference.class);
+        query.setParameter(JpaPortalPreference.PARAM_KEY, key);
+        return getSingleResult(query.getResultList());
+    }
+
+    @Override
+    public Class<? extends PortalPreference> getType() {
+        return JpaPortalPreference.class;
+    }
+
+    @Override
+    public PortalPreference get(long id) {
+        return manager.find(JpaPortalPreference.class, id);
+    }
+
+    @Override
+    public PortalPreference save(PortalPreference item) {
+        JpaPortalPreference pref = converter.convert(item);
+        return saveOrUpdate(pref.getEntityId(), manager, pref);
+    }
+
+    @Override
+    public void delete(PortalPreference item) {
+        manager.remove(converter.convert(item));
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionRepository.java
new file mode 100644
index 0000000..373caa0
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionRepository.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaRegion;
+import org.apache.rave.portal.model.Region;
+import org.apache.rave.portal.model.conversion.JpaRegionConverter;
+import org.apache.rave.portal.repository.RegionRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+
+@Repository
+public class JpaRegionRepository implements RegionRepository {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaRegionConverter regionConverter;
+
+    @Override
+    public Class<? extends Region> getType() {
+        return JpaRegion.class;
+    }
+
+    @Override
+    public Region get(long id) {
+        return manager.find(JpaRegion.class, id);
+    }
+
+    @Override
+    public Region save(Region item) {
+        JpaRegion region = regionConverter.convert(item);
+        return saveOrUpdate(region.getEntityId(), manager, region);
+    }
+
+    @Override
+    public void delete(Region item) {
+        manager.remove(item instanceof JpaRegion ? item : get(item.getId()));
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepository.java
new file mode 100644
index 0000000..fe40439
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepository.java
@@ -0,0 +1,64 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.repository.impl;

+

+import org.apache.rave.portal.model.JpaRegionWidget;

+import org.apache.rave.portal.model.RegionWidget;

+import org.apache.rave.portal.model.conversion.JpaRegionWidgetConverter;

+import org.apache.rave.portal.repository.RegionWidgetRepository;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.stereotype.Repository;

+

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

+

+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;

+

+

+@Repository

+public class JpaRegionWidgetRepository implements RegionWidgetRepository {

+

+    @PersistenceContext

+    private EntityManager manager;

+

+    @Autowired

+    private JpaRegionWidgetConverter regionWidgetConverter;

+

+    @Override

+    public Class<? extends RegionWidget> getType() {

+        return JpaRegionWidget.class;

+    }

+

+    @Override

+    public RegionWidget get(long id) {

+        return manager.find(JpaRegionWidget.class, id);

+    }

+

+    @Override

+    public RegionWidget save(RegionWidget item) {

+        JpaRegionWidget region = regionWidgetConverter.convert(item);

+        return saveOrUpdate(region.getEntityId(), manager, region);

+    }

+

+    @Override

+    public void delete(RegionWidget item) {

+        manager.remove(item instanceof JpaRegionWidget ? item : get(item.getId()));

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaTagRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaTagRepository.java
new file mode 100644
index 0000000..0474e9d
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaTagRepository.java
@@ -0,0 +1,102 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.repository.impl;

+

+import org.apache.rave.portal.model.JpaTag;

+import org.apache.rave.portal.model.Tag;

+import org.apache.rave.portal.model.conversion.JpaTagConverter;

+import org.apache.rave.portal.repository.TagRepository;

+import org.apache.rave.util.CollectionUtils;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.stereotype.Repository;

+

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

+import javax.persistence.Query;

+import javax.persistence.TypedQuery;

+import java.util.List;

+

+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;

+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;

+

+/**

+ * JPA implementation for {@link org.apache.rave.portal.repository.AuthorityRepository}

+ */

+@Repository

+public class JpaTagRepository implements TagRepository {

+

+    @PersistenceContext

+    private EntityManager manager;

+    

+    @Autowired

+    private JpaTagConverter converter;

+

+

+    @Override

+    public List<Tag> getAll() {

+        TypedQuery<JpaTag> query = manager.createNamedQuery(JpaTag.GET_ALL, JpaTag.class);

+        return CollectionUtils.<Tag>toBaseTypedList(query.getResultList());

+    }

+

+    @Override

+    public Class<? extends Tag> getType(){

+        return JpaTag.class;

+    }

+

+    @Override

+    public int getCountAll() {

+        Query query = manager.createNamedQuery(JpaTag.COUNT_ALL);

+        Number countResult = (Number) query.getSingleResult();

+        return countResult.intValue();

+    }

+

+    @Override

+    public JpaTag getByKeyword(String keyword) {

+        if (keyword != null) {

+            keyword = keyword.trim();

+        }

+        TypedQuery<JpaTag> query = manager.createNamedQuery(JpaTag.FIND_BY_KEYWORD, JpaTag.class);

+        query.setParameter("keyword", keyword);

+        return getSingleResult(query.getResultList());

+    }

+

+    @Override

+    public List<Tag> getAvailableTagsByWidgetId(Long widgetId) {

+        TypedQuery<JpaTag> query = manager.createNamedQuery(JpaTag.GET_ALL_NOT_IN_WIDGET, JpaTag.class);

+        query.setParameter("widgetId", widgetId);

+        return CollectionUtils.<Tag>toBaseTypedList(query.getResultList());

+    }

+

+    @Override

+    public Tag get(long id) {

+        return manager.find(JpaTag.class, id);

+    }

+

+    @Override

+    public Tag save(Tag item) {

+        JpaTag tag = converter.convert(item);

+        return saveOrUpdate(tag.getEntityId(), manager, tag);

+    }

+

+    @Override

+    public void delete(Tag item) {

+        manager.remove(item instanceof JpaTag ? item : getByKeyword(item.getKeyword()));

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaUserRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaUserRepository.java
new file mode 100644
index 0000000..854b478
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaUserRepository.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaUser;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.conversion.JpaUserConverter;
+import org.apache.rave.portal.repository.UserRepository;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.*;
+
+/**
+ */
+@Repository
+public class JpaUserRepository implements UserRepository {
+
+    @Autowired
+    private JpaUserConverter converter;
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Override
+    public User getByUsername(String username) {
+        TypedQuery<JpaUser> query = manager.createNamedQuery(JpaUser.USER_GET_BY_USERNAME, JpaUser.class);
+        query.setParameter(JpaUser.PARAM_USERNAME, username);
+        return getSingleResult(query.getResultList());
+    }
+
+    @Override
+    public User getByUserEmail(String userEmail) {
+        TypedQuery<JpaUser> query = manager.createNamedQuery(JpaUser.USER_GET_BY_USER_EMAIL, JpaUser.class);
+        query.setParameter(JpaUser.PARAM_EMAIL, userEmail);
+        return getSingleResult(query.getResultList());
+    }
+
+    @Override
+    public List<User> getLimitedList(int offset, int pageSize) {
+        TypedQuery<JpaUser> query = manager.createNamedQuery(JpaUser.USER_GET_ALL, JpaUser.class);
+        return CollectionUtils.<User>toBaseTypedList(getPagedResultList(query, offset, pageSize));
+    }
+
+    @Override
+    public int getCountAll() {
+        Query query = manager.createNamedQuery(JpaUser.USER_COUNT_ALL);
+        Number countResult = (Number) query.getSingleResult();
+        return countResult.intValue();
+    }
+
+    @Override
+    public List<User> findByUsernameOrEmail(String searchTerm, int offset, int pageSize) {
+        TypedQuery<JpaUser> query = manager.createNamedQuery(JpaUser.USER_FIND_BY_USERNAME_OR_EMAIL, JpaUser.class);
+        query.setParameter(JpaUser.PARAM_SEARCHTERM, "%" + searchTerm.toLowerCase() + "%");
+        return CollectionUtils.<User>toBaseTypedList(getPagedResultList(query, offset, pageSize));
+    }
+
+    @Override
+    public int getCountByUsernameOrEmail(String searchTerm) {
+        Query query = manager.createNamedQuery(JpaUser.USER_COUNT_FIND_BY_USERNAME_OR_EMAIL);
+        query.setParameter(JpaUser.PARAM_SEARCHTERM, "%" + searchTerm.toLowerCase() + "%");
+        Number countResult = (Number) query.getSingleResult();
+        return countResult.intValue();
+    }
+
+    @Override
+    public List<User> getAllByAddedWidget(long widgetId) {
+        TypedQuery<JpaUser> query = manager.createNamedQuery(JpaUser.USER_GET_ALL_FOR_ADDED_WIDGET, JpaUser.class);
+        query.setParameter(JpaUser.PARAM_WIDGET_ID, widgetId);
+        return CollectionUtils.<User>toBaseTypedList(query.getResultList());
+    }
+
+    @Override
+    public User getByForgotPasswordHash(String hash) {
+        TypedQuery<JpaUser> query = manager.createNamedQuery(JpaUser.USER_GET_BY_FORGOT_PASSWORD_HASH, JpaUser.class);
+        query.setParameter(JpaUser.PARAM_FORGOT_PASSWORD_HASH, hash);
+        return getSingleResult(query.getResultList());
+    }
+
+    @Override
+    public Class<? extends User> getType() {
+        return JpaUser.class;
+    }
+
+    @Override
+    public User get(long id) {
+        return manager.find(JpaUser.class, id);
+    }
+
+    @Override
+    public User save(User item) {
+        JpaUser converted = converter.convert(item);
+        return saveOrUpdate(converted.getEntityId(), manager, converted);
+    }
+
+    @Override
+    public void delete(User item) {
+       manager.remove(converter.convert(item));
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepository.java
new file mode 100644
index 0000000..b87173e
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepository.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaWidgetComment;
+import org.apache.rave.portal.model.WidgetComment;
+import org.apache.rave.portal.model.conversion.JpaWidgetCommentConverter;
+import org.apache.rave.portal.repository.WidgetCommentRepository;
+import org.apache.rave.util.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+@Repository
+public class JpaWidgetCommentRepository implements WidgetCommentRepository {
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaWidgetCommentConverter widgetCommentConverter;
+
+    @Override
+    public Class<? extends WidgetComment> getType() {
+        return JpaWidgetComment.class;
+    }
+
+    @Override
+    public WidgetComment get(long id) {
+        return manager.find(JpaWidgetComment.class, id);
+    }
+
+    @Override
+    public WidgetComment save(WidgetComment item) {
+        JpaWidgetComment category = widgetCommentConverter.convert(item);
+        return saveOrUpdate(category.getEntityId(), manager, category);
+    }
+
+    @Override
+    public void delete(WidgetComment item) {
+        manager.remove(item instanceof JpaWidgetComment ? item : get(item.getId()));
+    }
+
+    @Override
+    public int deleteAll(Long userId) {
+        TypedQuery<JpaWidgetComment> query = manager.createNamedQuery(JpaWidgetComment.DELETE_ALL_BY_USER, JpaWidgetComment.class);
+        query.setParameter("userId", userId);
+        return query.executeUpdate();
+    }
+}
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepository.java
new file mode 100644
index 0000000..2dab868
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepository.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.repository.impl;
+
+import org.apache.rave.portal.model.JpaWidgetRating;
+import org.apache.rave.portal.model.WidgetRating;
+import org.apache.rave.portal.model.conversion.JpaWidgetRatingConverter;
+import org.apache.rave.portal.repository.WidgetRatingRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import java.util.List;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;
+
+/**
+ * JPA implementation for {@link org.apache.rave.portal.repository.WidgetRatingRepository}
+ */
+@Repository
+public class JpaWidgetRatingRepository implements WidgetRatingRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    private JpaWidgetRatingConverter converter;
+
+    @Override
+    public WidgetRating getByWidgetIdAndUserId(Long widgetId, Long userId) {
+        TypedQuery<JpaWidgetRating> query =
+                manager.createNamedQuery(JpaWidgetRating.WIDGET_RATING_BY_WIDGET_AND_USER, JpaWidgetRating.class);
+        query.setParameter(JpaWidgetRating.PARAM_WIDGET_ID, widgetId);
+        query.setParameter(JpaWidgetRating.PARAM_USER_ID, userId);
+        final List<JpaWidgetRating> resultList = query.getResultList();
+        return getSingleResult(resultList);
+    }
+
+    @Override
+    public int deleteAll(Long userId) {
+        TypedQuery<JpaWidgetRating> query = manager.createNamedQuery(JpaWidgetRating.DELETE_ALL_BY_USER, JpaWidgetRating.class);
+        query.setParameter("userId", userId);
+        return query.executeUpdate();
+    }
+
+    @Override
+    public Class<? extends WidgetRating> getType() {
+        return JpaWidgetRating.class;
+    }
+
+    @Override
+    public WidgetRating get(long id) {
+        return manager.find(JpaWidgetRating.class, id);
+    }
+
+    @Override
+    public WidgetRating save(WidgetRating item) {
+        JpaWidgetRating jpaItem = converter.convert(item);
+        return saveOrUpdate(jpaItem.getEntityId(), manager, jpaItem);
+    }
+
+    @Override
+    public void delete(WidgetRating item) {
+        manager.remove(converter.convert(item));
+    }
+}
\ No newline at end of file
diff --git a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java
similarity index 63%
rename from rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java
rename to rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java
index 046770a..3ae9579 100644
--- a/rave-components/rave-core/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetRepository.java
@@ -21,67 +21,67 @@
 
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.openjpa.jdbc.kernel.exps.ToLowerCase;
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
 import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.conversion.JpaWidgetConverter;
 import org.apache.rave.portal.model.util.WidgetStatistics;
 import org.apache.rave.portal.repository.WidgetRepository;
+import org.apache.rave.util.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
-import javax.persistence.NoResultException;
-import javax.persistence.Query;
-import javax.persistence.TypedQuery;
+import javax.persistence.*;
 import javax.persistence.criteria.*;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getPagedResultList;
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+import static org.apache.rave.persistence.jpa.util.JpaUtil.*;
 
 @Repository
-public class JpaWidgetRepository extends AbstractJpaRepository<Widget> implements WidgetRepository {
+public class JpaWidgetRepository implements WidgetRepository {
 
     private final Logger log = LoggerFactory.getLogger(JpaWidgetRepository.class);
 
-    public JpaWidgetRepository() {
-        super(Widget.class);
-    }
+    @Autowired
+    private JpaWidgetConverter converter;
+
+    @PersistenceContext
+    private EntityManager manager;
 
     @Override
     public List<Widget> getAll() {
         log.warn("Requesting potentially large resultset of Widget. No pagesize set.");
-        TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_ALL, Widget.class);
-        return query.getResultList();
+        TypedQuery<JpaWidget> query = manager.createNamedQuery(JpaWidget.WIDGET_GET_ALL, JpaWidget.class);
+        return CollectionUtils.<Widget>toBaseTypedList(query.getResultList());
     }
 
     @Override
     public List<Widget> getLimitedList(int offset, int pageSize) {
-        TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_ALL, Widget.class);
-        return getPagedResultList(query, offset, pageSize);
+        TypedQuery<JpaWidget> query = manager.createNamedQuery(JpaWidget.WIDGET_GET_ALL, JpaWidget.class);
+        return CollectionUtils.<Widget>toBaseTypedList(getPagedResultList(query, offset, pageSize));
     }
 
     @Override
     public int getCountAll() {
-        Query query = manager.createNamedQuery(Widget.WIDGET_COUNT_ALL);
+        Query query = manager.createNamedQuery(JpaWidget.WIDGET_COUNT_ALL);
         Number countResult = (Number) query.getSingleResult();
         return countResult.intValue();
     }
 
     @Override
     public List<Widget> getByFreeTextSearch(String searchTerm, int offset, int pageSize) {
-        TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_BY_FREE_TEXT,
-                Widget.class);
+        TypedQuery<JpaWidget> query = manager.createNamedQuery(JpaWidget.WIDGET_GET_BY_FREE_TEXT,
+                JpaWidget.class);
         setFreeTextSearchTerm(query, searchTerm);
-        return getPagedResultList(query, offset, pageSize);
+        return CollectionUtils.<Widget>toBaseTypedList(getPagedResultList(query, offset, pageSize));
     }
 
     @Override
     public int getCountFreeTextSearch(String searchTerm) {
-        Query query = manager.createNamedQuery(Widget.WIDGET_COUNT_BY_FREE_TEXT);
+        Query query = manager.createNamedQuery(JpaWidget.WIDGET_COUNT_BY_FREE_TEXT);
         setFreeTextSearchTerm(query, searchTerm);
         Number countResult = (Number) query.getSingleResult();
         return countResult.intValue();
@@ -89,16 +89,16 @@
 
     @Override
     public List<Widget> getByStatus(WidgetStatus widgetStatus, int offset, int pageSize) {
-        TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_BY_STATUS,
-                Widget.class);
-        query.setParameter(Widget.PARAM_STATUS, widgetStatus);
-        return getPagedResultList(query, offset, pageSize);
+        TypedQuery<JpaWidget> query = manager.createNamedQuery(JpaWidget.WIDGET_GET_BY_STATUS,
+                JpaWidget.class);
+        query.setParameter(JpaWidget.PARAM_STATUS, widgetStatus);
+        return CollectionUtils.<Widget>toBaseTypedList(getPagedResultList(query, offset, pageSize));
     }
 
     @Override
     public int getCountByStatus(WidgetStatus widgetStatus) {
-        Query query = manager.createNamedQuery(Widget.WIDGET_COUNT_BY_STATUS);
-        query.setParameter(Widget.PARAM_STATUS, widgetStatus);
+        Query query = manager.createNamedQuery(JpaWidget.WIDGET_COUNT_BY_STATUS);
+        query.setParameter(JpaWidget.PARAM_STATUS, widgetStatus);
         Number countResult = (Number) query.getSingleResult();
         return countResult.intValue();
     }
@@ -107,19 +107,19 @@
     public List<Widget> getByStatusAndTypeAndFreeTextSearch(WidgetStatus widgetStatus, String type, String searchTerm,
                                                             int offset, int pageSize) {
         final CriteriaBuilder cb = manager.getCriteriaBuilder();
-        final CriteriaQuery<Widget> query = cb.createQuery(Widget.class);
-        final Root<Widget> widgetType = query.from(Widget.class);
+        final CriteriaQuery<JpaWidget> query = cb.createQuery(JpaWidget.class);
+        final Root<JpaWidget> widgetType = query.from(JpaWidget.class);
         query.where(getStatusAndTypeAndFreeTextPredicates(cb, widgetType, widgetStatus, type, searchTerm));
         query.orderBy(getOrderByTitleAsc(cb, widgetType));
 
-        return getPagedResultList(manager.createQuery(query), offset, pageSize);
+        return CollectionUtils.<Widget>toBaseTypedList(getPagedResultList(manager.createQuery(query), offset, pageSize));
     }
 
     @Override
     public int getCountByStatusAndTypeAndFreeText(WidgetStatus widgetStatus, String type, String searchTerm) {
         final CriteriaBuilder cb = manager.getCriteriaBuilder();
         final CriteriaQuery<Long> query = cb.createQuery(Long.class);
-        final Root<Widget> widgetType = query.from(Widget.class);
+        final Root<JpaWidget> widgetType = query.from(JpaWidget.class);
         query.select(cb.count(widgetType));
         query.where(getStatusAndTypeAndFreeTextPredicates(cb, widgetType, widgetStatus, type, searchTerm));
 
@@ -129,29 +129,29 @@
 
     @Override
     public List<Widget> getByOwner(User owner, int offset, int pageSize) {
-        TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_BY_OWNER, Widget.class);
-        query.setParameter(Widget.PARAM_OWNER, owner);
-        return getPagedResultList(query, offset, pageSize);
+        TypedQuery<JpaWidget> query = manager.createNamedQuery(JpaWidget.WIDGET_GET_BY_OWNER, JpaWidget.class);
+        query.setParameter(JpaWidget.PARAM_OWNER, owner);
+        return CollectionUtils.<Widget>toBaseTypedList(getPagedResultList(query, offset, pageSize));
     }
 
     @Override
     public int getCountByOwner(User owner, int offset, int pageSize) {
-        Query query = manager.createNamedQuery(Widget.WIDGET_COUNT_BY_OWNER);
-        query.setParameter(Widget.PARAM_OWNER, owner);
+        Query query = manager.createNamedQuery(JpaWidget.WIDGET_COUNT_BY_OWNER);
+        query.setParameter(JpaWidget.PARAM_OWNER, owner);
         Number countResult = (Number) query.getSingleResult();
         return countResult.intValue();
     }
 
     @Override
-    public Widget getByUrl(String widgetUrl) {
+    public JpaWidget getByUrl(String widgetUrl) {
         if (StringUtils.isBlank(widgetUrl)) {
             throw new IllegalArgumentException("Widget URL must not be empty");
         }
 
-        TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_BY_URL, Widget.class);
+        TypedQuery<JpaWidget> query = manager.createNamedQuery(JpaWidget.WIDGET_GET_BY_URL, JpaWidget.class);
         // url is a unique field, so no paging needed
-        query.setParameter(Widget.PARAM_URL, widgetUrl);
-        final List<Widget> resultList = query.getResultList();
+        query.setParameter(JpaWidget.PARAM_URL, widgetUrl);
+        final List<JpaWidget> resultList = query.getResultList();
         return getSingleResult(resultList);
     }
 
@@ -159,25 +159,25 @@
     public WidgetStatistics getWidgetStatistics(long widget_id, long user_id) {
         WidgetStatistics widgetStatistics = new WidgetStatistics();
 
-        Query query = manager.createNamedQuery(WidgetRating.WIDGET_TOTAL_LIKES);
-        query.setParameter(WidgetRating.PARAM_WIDGET_ID, widget_id);
+        Query query = manager.createNamedQuery(JpaWidgetRating.WIDGET_TOTAL_LIKES);
+        query.setParameter(JpaWidgetRating.PARAM_WIDGET_ID, widget_id);
         widgetStatistics.setTotalLike(((Number) query.getSingleResult()).intValue());
 
-        query = manager.createNamedQuery(WidgetRating.WIDGET_TOTAL_DISLIKES);
-        query.setParameter(WidgetRating.PARAM_WIDGET_ID, widget_id);
+        query = manager.createNamedQuery(JpaWidgetRating.WIDGET_TOTAL_DISLIKES);
+        query.setParameter(JpaWidgetRating.PARAM_WIDGET_ID, widget_id);
         widgetStatistics.setTotalDislike(((Number) query.getSingleResult()).intValue());
 
-        query = manager.createNamedQuery(RegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_SINGLE_WIDGET);
-        query.setParameter(RegionWidget.PARAM_WIDGET_ID, widget_id);
+        query = manager.createNamedQuery(JpaRegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_SINGLE_WIDGET);
+        query.setParameter(JpaRegionWidget.PARAM_WIDGET_ID, widget_id);
         widgetStatistics.setTotalUserCount(((Number) query.getSingleResult()).intValue());
 
         try {
-            query = manager.createNamedQuery(WidgetRating.WIDGET_USER_RATING);
-            query.setParameter(WidgetRating.PARAM_WIDGET_ID, widget_id);
-            query.setParameter(WidgetRating.PARAM_USER_ID, user_id);
+            query = manager.createNamedQuery(JpaWidgetRating.WIDGET_USER_RATING);
+            query.setParameter(JpaWidgetRating.PARAM_WIDGET_ID, widget_id);
+            query.setParameter(JpaWidgetRating.PARAM_USER_ID, user_id);
             widgetStatistics.setUserRating(((Number) query.getSingleResult()).intValue());
         } catch (NoResultException e) {
-            widgetStatistics.setUserRating(WidgetRating.UNSET);
+            widgetStatistics.setUserRating(JpaWidgetRating.UNSET);
         }
 
         return widgetStatistics;
@@ -185,9 +185,9 @@
 
     @Override
     public Map<Long, WidgetRating> getUsersWidgetRatings(long user_id) {
-        TypedQuery<WidgetRating> query =
-                manager.createNamedQuery(WidgetRating.WIDGET_ALL_USER_RATINGS, WidgetRating.class);
-        query.setParameter(WidgetRating.PARAM_USER_ID, user_id);
+        TypedQuery<JpaWidgetRating> query =
+                manager.createNamedQuery(JpaWidgetRating.WIDGET_ALL_USER_RATINGS, JpaWidgetRating.class);
+        query.setParameter(JpaWidgetRating.PARAM_USER_ID, user_id);
 
         Map<Long, WidgetRating> map = new HashMap<Long, WidgetRating>();
         for (WidgetRating widgetRating : query.getResultList()) {
@@ -203,7 +203,7 @@
         HashMap<Long, WidgetStatistics> map = new HashMap<Long, WidgetStatistics>();
 
         //Generate the mapping of all likes done for the widgets
-        Query query = manager.createNamedQuery(WidgetRating.WIDGET_ALL_TOTAL_LIKES);
+        Query query = manager.createNamedQuery(JpaWidgetRating.WIDGET_ALL_TOTAL_LIKES);
         for (Object[] result : (List<Object[]>) query.getResultList()) {
             Long totalLikes = (Long) result[0];
             Long widgetId = (Long) result[1];
@@ -213,7 +213,7 @@
         }
 
         //Add the mapping of all dislikes done for the widgets
-        query = manager.createNamedQuery(WidgetRating.WIDGET_ALL_TOTAL_DISLIKES);
+        query = manager.createNamedQuery(JpaWidgetRating.WIDGET_ALL_TOTAL_DISLIKES);
         for (Object[] result : (List<Object[]>) query.getResultList()) {
             Long totalDislikes = (Long) result[0];
             Long widgetId = (Long) result[1];
@@ -226,7 +226,7 @@
         }
 
         //get the total user count for widgets
-        query = manager.createNamedQuery(RegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_ALL_WIDGETS);
+        query = manager.createNamedQuery(JpaRegionWidget.REGION_WIDGET_GET_DISTINCT_USER_COUNT_ALL_WIDGETS);
         for (Object[] result : (List<Object[]>) query.getResultList()) {
             Long widgetId = (Long) result[0];
             Long totalUserCount = (Long) result[1];
@@ -247,7 +247,7 @@
             }
             //otherwise set the rating to UNSET
             else {
-                entry.getValue().setUserRating(WidgetRating.UNSET);
+                entry.getValue().setUserRating(JpaWidgetRating.UNSET);
             }
         }
 
@@ -257,27 +257,47 @@
     @Override
     public List<Widget> getWidgetsByTag(String tagKeyword, int offset, int pageSize) {
         if (tagKeyword!=null) tagKeyword =tagKeyword.toLowerCase();
-        TypedQuery<Widget> query = manager.createNamedQuery(Widget.WIDGET_GET_BY_TAG, Widget.class);
-        query.setParameter(Widget.PARAM_TAG, tagKeyword.toLowerCase());
-        return getPagedResultList(query, offset, pageSize);
+        TypedQuery<JpaWidget> query = manager.createNamedQuery(JpaWidget.WIDGET_GET_BY_TAG, JpaWidget.class);
+        query.setParameter(JpaWidget.PARAM_TAG, tagKeyword.toLowerCase());
+        return CollectionUtils.<Widget>toBaseTypedList(getPagedResultList(query, offset, pageSize));
     }
 
     @Override
     public int getCountByTag(String tagKeyword) {
         if (tagKeyword!=null) tagKeyword =tagKeyword.toLowerCase();
-        Query query = manager.createNamedQuery(Widget.WIDGET_COUNT_BY_TAG);
-        query.setParameter(Widget.PARAM_TAG,tagKeyword);
+        Query query = manager.createNamedQuery(JpaWidget.WIDGET_COUNT_BY_TAG);
+        query.setParameter(JpaWidget.PARAM_TAG,tagKeyword);
         Number countResult = (Number) query.getSingleResult();
         return countResult.intValue();
     }
 
     @Override
     public int unassignWidgetOwner(long userId) {
-        Query query = manager.createNamedQuery(Widget.WIDGET_UNASSIGN_OWNER);
-        query.setParameter(Widget.PARAM_OWNER, userId);
+        Query query = manager.createNamedQuery(JpaWidget.WIDGET_UNASSIGN_OWNER);
+        query.setParameter(JpaWidget.PARAM_OWNER, userId);
         return query.executeUpdate();
     }
 
+    @Override
+    public Class<? extends Widget> getType() {
+        return JpaWidget.class;
+    }
+
+    @Override
+    public Widget get(long id) {
+        return manager.find(JpaWidget.class, id);
+    }
+
+    @Override
+    public Widget save(Widget item) {
+        return saveOrUpdate(item.getId(), manager, converter.convert(item));
+    }
+
+    @Override
+    public void delete(Widget item) {
+        manager.remove(converter.convert(item));
+    }
+
     /**
      * Sets input as free text search term to a query
      *
@@ -285,10 +305,10 @@
      * @param searchTerm free text
      */
     protected void setFreeTextSearchTerm(Query query, final String searchTerm) {
-        query.setParameter(Widget.PARAM_SEARCH_TERM, getLowercaseWildcardSearchTerm(searchTerm));
+        query.setParameter(JpaWidget.PARAM_SEARCH_TERM, getLowercaseWildcardSearchTerm(searchTerm));
     }
 
-    private Predicate[] getStatusAndTypeAndFreeTextPredicates(CriteriaBuilder cb, Root<Widget> widgetType,
+    private Predicate[] getStatusAndTypeAndFreeTextPredicates(CriteriaBuilder cb, Root<JpaWidget> widgetType,
                                                               WidgetStatus widgetStatus, String type,
                                                               String searchTerm) {
         List<Predicate> predicates = new ArrayList<Predicate>();
@@ -310,23 +330,23 @@
         return predicates.toArray(new Predicate[predicates.size()]);
     }
 
-    private Order getOrderByTitleAsc(CriteriaBuilder cb, Root<Widget> widgetType) {
+    private Order getOrderByTitleAsc(CriteriaBuilder cb, Root<JpaWidget> widgetType) {
         return cb.asc(getTitleField(widgetType));
     }
 
-    private Path<String> getTitleField(Root<Widget> widgetType) {
+    private Path<String> getTitleField(Root<JpaWidget> widgetType) {
         return widgetType.get("title");
     }
 
-    private Path<String> getDescriptionField(Root<Widget> widgetType) {
+    private Path<String> getDescriptionField(Root<JpaWidget> widgetType) {
         return widgetType.get("description");
     }
 
-    private Path<String> getTypeField(Root<Widget> widgetType) {
+    private Path<String> getTypeField(Root<JpaWidget> widgetType) {
         return widgetType.get("type");
     }
 
-    private Path<WidgetStatus> getWidgetStatusField(Root<Widget> widgetType) {
+    private Path<WidgetStatus> getWidgetStatusField(Root<JpaWidget> widgetType) {
         return widgetType.get("widgetStatus");
     }
 
diff --git a/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepository.java b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepository.java
new file mode 100644
index 0000000..a8f850c
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepository.java
@@ -0,0 +1,78 @@
+/*

+ * Copyright 2011 The Apache Software Foundation.

+ *

+ * 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.rave.portal.repository.impl;

+

+import org.apache.rave.portal.model.JpaTag;

+import org.apache.rave.portal.model.JpaWidgetTag;

+import org.apache.rave.portal.model.WidgetTag;

+import org.apache.rave.portal.model.conversion.JpaWidgetTagConverter;

+import org.apache.rave.portal.repository.WidgetTagRepository;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.stereotype.Repository;

+

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

+import javax.persistence.TypedQuery;

+

+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;

+import static org.apache.rave.persistence.jpa.util.JpaUtil.saveOrUpdate;

+

+@Repository

+public class JpaWidgetTagRepository implements WidgetTagRepository {

+

+    @PersistenceContext

+    EntityManager manager;

+    

+    @Autowired

+    JpaWidgetTagConverter converter;

+

+    @Override

+    public JpaWidgetTag getByWidgetIdAndTag(Long widgetId, String keyword) {

+        if (keyword != null) {

+            keyword = keyword.trim();

+        }

+        TypedQuery<JpaWidgetTag> query = manager.createNamedQuery(JpaWidgetTag.FIND_BY_WIDGET_AND_KEYWORD, JpaWidgetTag.class);

+        query.setParameter("keyword", keyword);

+        query.setParameter("widgetId", widgetId);

+        return getSingleResult(query.getResultList());

+    }

+

+    @Override

+    public Class<? extends WidgetTag> getType() {

+        return JpaWidgetTag.class;

+    }

+

+    @Override

+    public WidgetTag get(long id) {

+        return manager.find(JpaWidgetTag.class, id);

+    }

+

+    @Override

+    public WidgetTag save(WidgetTag item) {

+        JpaWidgetTag widgetTag = converter.convert(item);

+        //We know this cast will succeed since we are dealing with a JpaWidgetTag

+        //since  this is a reciprocal relationship, we need to make sure we save one side of it first

+        JpaTag tag = (JpaTag)widgetTag.getTag();

+        item.setTag(saveOrUpdate(tag.getEntityId(), manager, tag));

+

+        return saveOrUpdate(widgetTag.getEntityId(), manager, widgetTag);

+    }

+

+    @Override

+    public void delete(WidgetTag item) {

+        manager.remove(item instanceof JpaWidgetTag ? item: getByWidgetIdAndTag(item.getWidgetId(), item.getTag().getKeyword()));

+    }

+}

diff --git a/rave-components/rave-jpa/src/main/resources/META-INF/persistence.xml b/rave-components/rave-jpa/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..3177ba5
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you 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.
+  -->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+            version="2.0">
+        <persistence-unit name="ravePersistenceUnit" transaction-type="RESOURCE_LOCAL">
+            <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+            <class>org.apache.rave.portal.model.JpaPage</class>
+            <class>org.apache.rave.portal.model.JpaRegion</class>
+            <class>org.apache.rave.portal.model.JpaUser</class>
+            <class>org.apache.rave.portal.model.JpaRegionWidget</class>
+            <class>org.apache.rave.portal.model.JpaRegionWidgetPreference</class>
+            <class>org.apache.rave.portal.model.JpaWidget</class>
+            <class>org.apache.rave.portal.model.JpaWidgetComment</class>
+            <class>org.apache.rave.portal.model.JpaWidgetRating</class>
+            <class>org.apache.rave.portal.model.JpaPageLayout</class>
+            <class>org.apache.rave.portal.model.JpaAuthority</class>
+            <class>org.apache.rave.portal.model.JpaTag</class>
+            <class>org.apache.rave.portal.model.JpaWidgetTag</class>
+            <class>org.apache.rave.portal.model.JpaPortalPreference</class>
+            <class>org.apache.rave.portal.model.JpaPageTemplate</class>
+            <class>org.apache.rave.portal.model.JpaPageTemplateRegion</class>
+            <class>org.apache.rave.portal.model.JpaPageTemplateWidget</class>
+            <class>org.apache.rave.portal.model.JpaPageUser</class>
+            <class>org.apache.rave.portal.model.JpaCategory</class>
+            <class>org.apache.rave.portal.model.JpaPerson</class>
+            <class>org.apache.rave.portal.model.JpaGroup</class>
+            <class>org.apache.rave.portal.model.JpaPersonAssociation</class>
+            <class>org.apache.rave.portal.model.JpaPersonProperty</class>
+            <class>org.apache.rave.portal.model.JpaAddress</class>
+            <class>org.apache.rave.portal.model.JpaOrganization</class>
+            <class>org.apache.rave.portal.model.JpaApplicationData</class>
+            <class>org.apache.rave.portal.model.JpaOAuthTokenInfo</class>
+            <class>org.apache.rave.portal.model.JpaOAuthConsumerStore</class>
+            <class>org.apache.rave.portal.repository.impl.JpaApplicationDataRepository$JpaSerializableApplicationData</class>
+        </persistence-unit>
+</persistence>
diff --git a/rave-components/rave-jpa/src/main/resources/org/apache/rave/jpa-applicationContext.xml b/rave-components/rave-jpa/src/main/resources/org/apache/rave/jpa-applicationContext.xml
new file mode 100644
index 0000000..4ffc638
--- /dev/null
+++ b/rave-components/rave-jpa/src/main/resources/org/apache/rave/jpa-applicationContext.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+  
+  $Id$
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
+        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
+        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
+        http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1.xsd
+        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
+
+    <!-- make the the portal.properties props available to autowire injectors, location of the properties can
+     be overridden by setting a system property "portal.override.properties" -->
+    <bean id="portalPropertyPlaceholder" class="org.apache.rave.util.OverridablePropertyPlaceholderConfigurer">
+        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
+        <property name="systemPropertyName" value="portal.override.properties"/>
+        <property name="location" value="classpath:portal.properties"/>
+    </bean>
+
+    <!-- bean post-processor for JPA annotations -->
+    <context:annotation-config/>
+
+    <!-- enable the use of the @AspectJ style of Spring AOP -->
+    <aop:aspectj-autoproxy/>
+
+    <!-- rave-common component base-package scan (maybe move to a separate common-applicationContext.xml?) -->
+    <context:component-scan base-package="org.apache.rave.service"/>
+    <context:component-scan base-package="org.apache.rave.synchronization"/>
+
+    <!-- rave-core component base-package scan -->
+    <context:component-scan base-package="org.apache.rave.portal.model"/>
+    <context:component-scan base-package="org.apache.rave.portal.repository"/>
+
+    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
+        <property name="entityManagerFactory" ref="entityManagerFactory"/>
+    </bean>
+
+    <tx:annotation-driven transaction-manager="transactionManager"/>
+
+    <bean id="entityManagerFactory"
+          class="org.apache.rave.persistence.jpa.PopulatedLocalContainerEntityManagerFactory">
+        <property name="populator" ref="dataSourcePopulator"/>
+        <property name="loadTimeWeaver">
+            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
+        </property>
+        <property name="persistenceUnitName" value="ravePersistenceUnit"/>
+        <property name="dataSource" ref="dataSource"/>
+        <property name="jpaVendorAdapter">
+            <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
+                  p:databasePlatform="${portal.jpaVendorAdapter.databasePlatform}"
+                  p:database="${portal.jpaVendorAdapter.database}"
+                  p:showSql="${portal.jpaVendorAdapter.showSql}"/>
+        </property>
+        <property name="jpaDialect">
+            <bean class="${portal.jpaDialect}"/>
+        </property>
+        <property name="jpaPropertyMap">
+            <map>
+                <entry key="openjpa.Log" value="${portal.openjpa.Log}"/>
+                <entry key="openjpa.RuntimeUnenhancedClasses" value="${portal.openjpa.RuntimeUnenhancedClasses}"/>
+                <entry key="openjpa.jdbc.SynchronizeMappings" value="${portal.openjpa.jdbc.SynchronizeMappings}"/>
+                <entry key="openjpa.jdbc.MappingDefaults" value="${portal.openjpa.jdbc.MappingDefaults}"/>
+            </map>
+        </property>
+    </bean>
+
+    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+        <property name="url" value="${portal.dataSource.url}"/>
+        <property name="driverClassName" value="${portal.dataSource.driver}"/>
+        <property name="username" value="${portal.dataSource.username}"/>
+        <property name="password" value="${portal.dataSource.password}"/>
+    </bean>
+
+    <!-- Password encoding -->
+    <bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder">
+        <!--<constructor-arg index="0" value="10"/>-->
+    </bean>
+
+    <!-- email settings -->
+    <bean id="emailServiceMailMessage" class="org.springframework.mail.SimpleMailMessage">
+        <property name="from" value="${portal.mail.sender}"/>
+        <property name="replyTo" value="${portal.mail.replyto}"/>
+    </bean>
+
+    <bean id="freemarkerMailConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
+        <property name="templateLoaderPath" value="/WEB-INF/mailtemplates"/>
+    </bean>
+    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
+        <property name="host" value="${portal.mail.host}"/>
+        <property name="password" value="${portal.mail.password}"/>
+        <property name="username" value="${portal.mail.username}"/>
+        <property name="port" value="${portal.mail.port}"/>
+        <property name="protocol" value="${portal.mail.protocol}"/>
+        <!-- NOTE: if using Gmail, you'll need following properties-->
+        <!--<property name="javaMailProperties">
+            <props>
+                <prop key="mail.smtp.auth">true</prop>
+                <prop key="mail.smtp.starttls.enable">true</prop>
+                <prop key="mail.smtp.timeout">8500</prop>
+            </props>
+        </property>-->
+    </bean>
+    <!--
+    NOTE: to use mail session you'll need to configure following within catalina_home/conf/context.xml
+    <Resource name="mail/Session" auth="Container" type="javax.mail.Session" mail.smtp.host="my.mail.host"/>
+
+    Further, activation & mail jars needs to be placed within catalina_home/lib folder
+    -->
+    <!--
+    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
+        <property name="session" ref="mailSession"/>
+    </bean>
+    <bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
+        <property name="jndiName" value="java:comp/env/mail/Session"/>
+    </bean>
+    -->
+
+    <bean id="restTemplate" class="org.springframework.web.client.RestTemplate" />
+
+    <bean id="staticContentCache" class="org.apache.rave.service.impl.DefaultStaticContentFetcherService">
+        <constructor-arg ref="restTemplate"/>
+        <constructor-arg>
+            <list>
+                <!-- example of a Static Content source that doesn't have any string token placeholders in its content body
+                <bean class="org.apache.rave.model.StaticContent">
+                    <constructor-arg index="0" value="standardCompanyHeader"/>
+                    <constructor-arg index="1" value="${company.header.host}/content/standard_header.html"/>
+                    <constructor-arg index="2">
+                        <null/>
+                    </constructor-arg>
+                </bean>
+                -->
+                <!-- example of a Static Content source that has string token placeholders
+                <bean class="org.apache.rave.model.StaticContent">
+                    <constructor-arg index="0" value="environmentSpecificContent"/>
+                    <constructor-arg index="1" value="${company.header.host}/content/footer.html"/>
+                    <constructor-arg index="2">
+                        <map>
+                            <entry key="\{supportEmail\}" value="${raveproperty.supportemail}"/>
+                            <entry key="\{productVersion\}" value="${raveproperty.version}"/>
+                        </map>
+                    </constructor-arg>
+                </bean>
+                -->
+            </list>
+        </constructor-arg>
+    </bean>
+
+    <!-- example on how to setup a Spring Timer to refresh the Static Content cache at a fixed interval
+    <bean id="refreshStaticContentCacheScheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
+        <property name="delay" value="5000"/>
+        <property name="period" value="300000"/>
+        <property name="timerTask">
+            <bean class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean"
+                  p:targetObject-ref="staticContentCache" p:targetMethod="refreshAll"/>
+        </property>
+    </bean>
+    <bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
+        <property name="daemon" value="true"/>
+        <property name="scheduledTimerTasks">
+            <list>
+                <ref local="refreshStaticContentCacheScheduledTask"/>
+            </list>
+        </property>
+    </bean>
+    -->
+</beans>
\ No newline at end of file
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/AuthorityTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/AuthorityTest.java
similarity index 92%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/AuthorityTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/AuthorityTest.java
index 66605f3..f76aa9f 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/AuthorityTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/AuthorityTest.java
@@ -25,13 +25,13 @@
 import static junit.framework.Assert.assertEquals;
 
 /**
- * Test for {@link Authority}
+ * Test for {@link JpaAuthority}
  */
 public class AuthorityTest {
 
     @Test
     public void testAuthority() throws Exception {
-        GrantedAuthority grantedAuthority = new Authority();
+        GrantedAuthority grantedAuthority = new JpaAuthority();
         ((Authority) grantedAuthority).setAuthority("user");
         assertEquals("user", grantedAuthority.getAuthority());
 
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/PageTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/PageTest.java
similarity index 73%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/PageTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/PageTest.java
index 54c3a22..addcdd8 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/PageTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/PageTest.java
@@ -18,25 +18,33 @@
  */
 package org.apache.rave.portal.model;
 
+import org.apache.rave.portal.model.impl.PageImpl;
+import org.apache.rave.portal.model.impl.PageLayoutImpl;
+import org.apache.rave.portal.model.impl.PageUserImpl;
+import org.apache.rave.portal.model.impl.RegionImpl;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Tests the Page class.
  */
+// TODO - remove ignore once Page is refactored into interface
+@Ignore
 public class PageTest {
 	private Page page;
 	private long id;
 	private long parentId;
 	private String testName;
-	private User testOwner;
+	private JpaUser testOwner;
     private Page parentPage;
     private List<Page> subPages;
 	private PageLayout pageLayout;
@@ -49,23 +57,23 @@
 
 	@Before
 	public void setup(){
-		page=new Page();
+		page=new PageImpl();
 		id=19191991L;
         parentId = 12345L;
 		testName="testName";
-		testOwner=new User(id);
-        parentPage = new Page(parentId);
+		testOwner=new JpaUser(id);
+        parentPage = new PageImpl(parentId);
         subPages = new ArrayList<Page>();
 
-        Page subPage1 = new Page();
-        subPage1.setEntityId(SUB_PAGE_1_ID);
+        Page subPage1 = new PageImpl();
+        subPage1.setId(SUB_PAGE_1_ID);
         subPage1.setOwner(testOwner);
-        Page subPage2 = new Page();
-        subPage2.setEntityId(SUB_PAGE_2_ID);
+        Page subPage2 = new PageImpl();
+        subPage2.setId(SUB_PAGE_2_ID);
         subPage2.setOwner(testOwner);
 
         List<PageUser> pageUsers1 = new ArrayList<PageUser>();
-        PageUser pageUser1 = new PageUser();
+        PageUser pageUser1 = new PageUserImpl();
         pageUser1.setUser(testOwner);
         pageUser1.setPage(subPage1);
         pageUser1.setRenderSequence(2L);
@@ -73,13 +81,13 @@
         subPage1.setMembers(pageUsers1);
 
         List<PageUser> pageUsers2 = new ArrayList<PageUser>();
-        PageUser pageUser2 = new PageUser();
-        pageUser2.setUser(new User());
+        PageUser pageUser2 = new PageUserImpl();
+        pageUser2.setUser(new JpaUser());
         pageUser2.setPage(subPage2);
         pageUser2.setRenderSequence(19L);
         pageUsers2.add(pageUser2);
 
-        PageUser pageUser3 = new PageUser();
+        PageUser pageUser3 = new PageUserImpl();
         pageUser3.setUser(testOwner);
         pageUser3.setPage(subPage2);
         pageUser3.setRenderSequence(1L);
@@ -88,14 +96,14 @@
 
         subPages.add(subPage1);
         subPages.add(subPage2);
-		pageLayout=new PageLayout();
+		pageLayout=new PageLayoutImpl();
 		renderSequence=1223L;
 
 		regions=new ArrayList<Region>();
-		regions.add(new Region());
-		regions.add(new Region());
+		regions.add(new RegionImpl());
+		regions.add(new RegionImpl());
 
-		page.setEntityId(id);
+		page.setId(id);
 		page.setName(testName);
 		page.setOwner(testOwner);
 		page.setParentPage(parentPage);
@@ -103,7 +111,7 @@
 		page.setPageLayout(pageLayout);
 		page.setRegions(regions);
 
-		pageUser = new PageUser();
+		pageUser = new PageUserImpl();
 		pageUser.setPage(page);
 		pageUser.setUser(testOwner);
 		pageUser.setRenderSequence(renderSequence);
@@ -116,7 +124,7 @@
 
 	@Test
 	public void testAccessorMethods() {
-		assertTrue(page.getEntityId()==id);
+		assertTrue(page.getId()==id);
 		assertTrue(page.getName().equals(testName));
 		assertTrue(page.getOwner().equals(testOwner));
 		assertTrue(page.getParentPage().equals(parentPage));
@@ -139,7 +147,7 @@
     public void testSubPageComparator() {
         Long previousRenderSequence = -999L;
         List<Page> subPages = page.getSubPages();
-        assertThat(subPages.get(0).getEntityId(), is(SUB_PAGE_2_ID));
-        assertThat(subPages.get(1).getEntityId(), is(SUB_PAGE_1_ID));
+        assertThat(subPages.get(0).getId(), is(SUB_PAGE_2_ID));
+        assertThat(subPages.get(1).getId(), is(SUB_PAGE_1_ID));
     }
 }
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/PortalPreferenceTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/PortalPreferenceTest.java
similarity index 86%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/PortalPreferenceTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/PortalPreferenceTest.java
index fe40e3f..54dc4c4 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/PortalPreferenceTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/PortalPreferenceTest.java
@@ -30,7 +30,7 @@
 import static junit.framework.Assert.assertNull;
 
 /**
- * Test for {@link PortalPreference}
+ * Test for {@link JpaPortalPreference}
  */
 public class PortalPreferenceTest {
     private static final String KEY = "foo";
@@ -39,7 +39,7 @@
     @Test
     public void testGettersSetters() throws Exception {
         Long entityId = 1L;
-        PortalPreference preference = new PortalPreference();
+        JpaPortalPreference preference = new JpaPortalPreference();
 
         assertNull(preference.getValue());
 
@@ -54,21 +54,21 @@
 
     @Test
     public void singleValuePreference() throws Exception {
-        PortalPreference preference = new PortalPreference(KEY, "bar");
+        PortalPreference preference = new JpaPortalPreference(KEY, "bar");
         assertEquals(KEY, preference.getKey());
         assertEquals("bar", preference.getValue());
     }
 
     @Test
     public void testGetValues() throws Exception {
-        PortalPreference preference = new PortalPreference(KEY, VALUES);
+        PortalPreference preference = new JpaPortalPreference(KEY, VALUES);
         assertEquals(KEY, preference.getKey());
         assertEquals(VALUES, preference.getValues());
     }
 
     @Test
     public void testSetValues() throws Exception {
-        PortalPreference preference = new PortalPreference(KEY, VALUES);
+        PortalPreference preference = new JpaPortalPreference(KEY, VALUES);
         assertEquals(KEY, preference.getKey());
         assertEquals(VALUES, preference.getValues());
         preference.setValue("tree");
@@ -79,7 +79,7 @@
 
     @Test(expected = NotSupportedException.class)
     public void getValueFailsForMultiValue() {
-        PortalPreference preference = new PortalPreference(KEY, VALUES);
+        PortalPreference preference = new JpaPortalPreference(KEY, VALUES);
         preference.getValue();
         assertFalse("Expected exception", true);
 
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/TagTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/TagTest.java
similarity index 92%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/TagTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/TagTest.java
index db2d9a2..72769af 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/TagTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/TagTest.java
@@ -24,13 +24,13 @@
 import static junit.framework.Assert.assertEquals;

 

 /**

- * Test for {@link org.apache.rave.portal.model.Authority}

+ * Test for {@link JpaAuthority}

  */

 public class TagTest {

 

     @Test

     public void testAuthority() throws Exception {

-        Tag tag = new Tag();

+        Tag tag = new JpaTag();

         tag.setKeyword("test");

         assertEquals("test", tag.getKeyword());

 

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/UserTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/UserTest.java
similarity index 90%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/UserTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/UserTest.java
index 933ade5..abb04ef 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/UserTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/UserTest.java
@@ -19,28 +19,29 @@
 package org.apache.rave.portal.model;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.Collection;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 /**
  * Tests the User class.
- */
+        */
+ @Ignore
 public class UserTest {
-    private User user1;
-    private User user2;
-    private User user3;
+    private JpaUser user1;
+    private JpaUser user2;
+    private JpaUser user3;
     private long id;
     private String userName;
     private String userPassword;
 
     @Before
     public void setup() {
+
         id = 123L;
         userName = "testUser";
         userPassword = "qwerty";
@@ -55,7 +56,7 @@
         boolean user3Expired = false;
 
 
-        user1 = new User();
+        user1 = new JpaUser();
         user1.setUsername(userName);
         user1.setEntityId(id);
         user1.setPassword(userPassword);
@@ -63,12 +64,12 @@
         user1.setExpired(user1Expired);
         user1.setLocked(user1Locked);
 
-        user2 = new User(id);
+        user2 = new JpaUser(id);
         user2.setExpired(user2Expired);
         user2.setEnabled(user2Enabled);
         user2.setLocked(user2Locked);
 
-        user3 = new User(id, userName);
+        user3 = new JpaUser(id, userName);
         user3.setExpired(user3Expired);
         user3.setEnabled(user3Enabled);
         user3.setLocked(user3Locked);
@@ -105,10 +106,10 @@
 
     @Test
     public void preRemove() {
-        User user = new User(123L, "DummyUser");
+        JpaUser user = new JpaUser(123L, "DummyUser");
 
         Collection<Authority> authorities = new ArrayList<Authority>();
-        Authority authority = new Authority();
+        JpaAuthority authority = new JpaAuthority();
         authority.setEntityId(456L);
         authority.setAuthority("DummyAuthority");
         authority.addUser(user);
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetRatingTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetRatingTest.java
similarity index 91%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetRatingTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetRatingTest.java
index 5c94972..b7bbb2a 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetRatingTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetRatingTest.java
@@ -30,7 +30,7 @@
 Test for {@link WidgetRatingTest}
  */
 public class WidgetRatingTest {
-    WidgetRating widgetRating;
+    JpaWidgetRating widgetRating;
     
     Long id;
     Long widgetId;
@@ -44,7 +44,7 @@
         userId = 1L;
         score = 1;
         
-        widgetRating = new WidgetRating();
+        widgetRating = new JpaWidgetRating();
         widgetRating.setEntityId(id);
         widgetRating.setScore(score);
         widgetRating.setUserId(userId);
@@ -61,14 +61,14 @@
     
     @Test
     public void equality() {
-        WidgetRating tester = new WidgetRating();
+        JpaWidgetRating tester = new JpaWidgetRating();
         tester.setEntityId(1L);
         
         assertEquals(widgetRating, tester);
         tester.setEntityId(2L);
         assertFalse(widgetRating.equals(tester));
         assertFalse(widgetRating.equals(null));
-        assertFalse(widgetRating.equals(new WidgetRating()));
+        assertFalse(widgetRating.equals(new JpaWidgetRating()));
         assertFalse(widgetRating.equals(new String()));
         
         widgetRating.toString();
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetTagTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetTagTest.java
similarity index 81%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetTagTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetTagTest.java
index 454b9cd..15643ed 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetTagTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetTagTest.java
@@ -16,18 +16,20 @@
 package org.apache.rave.portal.model;

 

 import org.junit.Before;

+import org.junit.Ignore;

 import org.junit.Test;

 

 import java.util.Date;

 

-import static org.junit.Assert.*;

+import static org.junit.Assert.assertEquals;

 

 /**

  *

  */

+@Ignore

 public class WidgetTagTest {

     

-    private WidgetTag widgetTag;

+    private JpaWidgetTag widgetTag;

     

     private static final Long VALID_ENTITY_ID = 1L;

     private static final Long VALID_USER_ID = 1L;

@@ -36,19 +38,19 @@
     

     @Before

     public void setUp() {

-        widgetTag = new WidgetTag();

+        widgetTag = new JpaWidgetTag();

         widgetTag.setEntityId(VALID_ENTITY_ID);

         widgetTag.setWidgetId(VALID_WIDGET_ID);

-        widgetTag.setUser(new User(1L, "John.Doe"));

+        widgetTag.setUser(new JpaUser(1L, "John.Doe"));

         widgetTag.setCreatedDate(VALID_CREATED_DATE);

-        widgetTag.setTag(new Tag(1L, "test"));

+        widgetTag.setTag(new JpaTag(1L, "test"));

     }

     

     @Test

     public void getters() {

         assertEquals(VALID_ENTITY_ID, widgetTag.getEntityId());

         assertEquals(VALID_WIDGET_ID, widgetTag.getWidgetId());

-        assertEquals(VALID_USER_ID, widgetTag.getUser().getEntityId());

+        assertEquals(VALID_USER_ID, widgetTag.getUser().getId());

         assertEquals(VALID_CREATED_DATE, widgetTag.getCreatedDate());

     }

     

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetTest.java
similarity index 88%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetTest.java
index 5910d7f..307a824 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/model/WidgetTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/WidgetTest.java
@@ -21,6 +21,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -28,13 +29,13 @@
 import java.util.List;
 
 import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
 
 /**
- * Test for {@link Widget}
+ * Test for {@link JpaWidget}
  */
+@Ignore
 public class WidgetTest {
-    private Widget widget;
+    private JpaWidget widget;
     private Long id;
     private String title;
     private String url;
@@ -50,7 +51,7 @@
     
     @Before
     public void setUp() throws Exception {
-        widget = new Widget();
+        widget = new JpaWidget();
         id = 3511L;
         title = "Test Widget";
         url = "http://example.com/widget.xml";
@@ -62,15 +63,15 @@
         status = WidgetStatus.PREVIEW;
         widgetComments = new ArrayList<WidgetComment>();
 
-        Tag tag=new Tag(1L, "test") ;
-        Tag tag1=new Tag(2L, "test1") ;
+        JpaTag tag=new JpaTag(1L, "test") ;
+        JpaTag tag1=new JpaTag(2L, "test1") ;
         
         ratings = new ArrayList<WidgetRating>();
-        ratings.add(new WidgetRating(1L, 1L, 1L, 1));
+        ratings.add(new JpaWidgetRating(1L, 1L, 1L, 1));
         
         tags = new ArrayList<WidgetTag>();
-        tags.add(new WidgetTag(1L, 1L, new User(), new Date(), tag)) ;
-        tags.add(new WidgetTag(2L,1L, new User(), new Date(), tag1)) ;
+        tags.add(new JpaWidgetTag(1L, 1L, new JpaUser(), new Date(), tag)) ;
+        tags.add(new JpaWidgetTag(2L,1L, new JpaUser(), new Date(), tag1)) ;
 
         widget.setEntityId(id);
         widget.setTitle(title);
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/ConvertingListProxyFactoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/ConvertingListProxyFactoryTest.java
new file mode 100644
index 0000000..7db0cfe
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/ConvertingListProxyFactoryTest.java
@@ -0,0 +1,141 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.model.impl.PersonImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+/**
+ */
+public class ConvertingListProxyFactoryTest {
+
+    // TODO: RAVE-689 temporary fix/workaround 
+    private static class StaticConvertersAccessor extends JpaConverter {
+        private StaticConvertersAccessor(List<ModelConverter> converters) {
+            super(converters);
+        }
+        public static Map<Class<?>, ModelConverter> getConverters() {        
+            return JpaConverter.isInstanceSet() ? JpaConverter.getInstance().converterMap : null;
+        }
+        public static void setConverters(Map<Class<?>, ModelConverter> converters) {
+           if (JpaConverter.isInstanceSet()) {
+               JpaConverter.getInstance().converterMap = converters;
+           }
+        }
+    }
+    
+    private Map<Class<?>, ModelConverter> savedConverters;
+    
+    @Before
+    public void setup() {
+        savedConverters = StaticConvertersAccessor.getConverters();
+    }
+    
+    @After
+    public void teardown() {
+        StaticConvertersAccessor.setConverters(savedConverters);
+    }
+    // end TODO: RAVE-689 temporary fix/workaround 
+
+    @Test
+    public void createProxy() {
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        replay(converterMock);
+        new JpaConverter(converters);
+        List<PersonImpl> underlying = new ArrayList<PersonImpl>();
+
+        List<Person> personProxy = ConvertingListProxyFactory.createProxyList(Person.class, underlying);
+        assertThat(Proxy.isProxyClass(personProxy.getClass()), is(true));
+    }
+
+    @Test
+    public void proxyAdd() {
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        Person personImpl1 = new PersonImpl();
+        PersonImpl personImpl2 = new PersonImpl();
+        expect(converterMock.convert(personImpl1)).andReturn(personImpl2);
+        replay(converterMock);
+        List<PersonImpl> underlying = createMock(List.class);
+        expect(underlying.add(personImpl2)).andReturn(true);
+        replay(underlying);
+        new JpaConverter(converters);
+
+
+        List<Person> personProxy = ConvertingListProxyFactory.createProxyList(Person.class, underlying);
+        Boolean good = personProxy.add(personImpl1);
+        assertThat(good, is(true));
+        verify(converterMock);
+        verify(underlying);
+    }
+
+    @Test
+    public void proxySet() {
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        Person personImpl1 = new PersonImpl();
+        Person personImpl2 = new PersonImpl();
+        expect(converterMock.convert(personImpl1)).andReturn(personImpl2);
+        replay(converterMock);
+        List<PersonImpl> underlying = createMock(List.class);
+        expect(underlying.set(0, (PersonImpl)personImpl2)).andReturn((PersonImpl) personImpl2);
+        replay(underlying);
+        new JpaConverter(converters);
+
+        List<Person> personProxy = ConvertingListProxyFactory.createProxyList(Person.class, underlying);
+        Person good = personProxy.set(0, personImpl1);
+        assertThat(good, is(sameInstance(personImpl2)));
+        verify(converterMock);
+        verify(underlying);
+    }
+
+    @Test
+    public void proxyAddAll() {
+
+        Person personImpl1 = new PersonImpl();
+        Person personImpl2 = new PersonImpl();
+        Person personImpl3 = new PersonImpl();
+        Person personImpl4 = new PersonImpl();
+
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        ModelConverter converterMock = createMock(ModelConverter.class);
+        expect(converterMock.getSourceType()).andReturn(Person.class).anyTimes();
+        converters.add(converterMock);
+        expect(converterMock.convert(personImpl1)).andReturn(personImpl2);
+        expect(converterMock.convert(personImpl3)).andReturn(personImpl4);
+        replay(converterMock);
+
+        List<Person> toAdd = new ArrayList<Person>();
+        toAdd.add(personImpl1);
+        toAdd.add(personImpl3);
+
+        List<PersonImpl> underlying = createMock(List.class);
+        expect(underlying.addAll(isA(List.class))).andReturn(true);
+        replay(underlying);
+        new JpaConverter(converters);
+
+        List<Person> personProxy = ConvertingListProxyFactory.createProxyList(Person.class, underlying);
+        Boolean good = personProxy.addAll(toAdd);
+        assertThat(good, is(true));
+        verify(converterMock);
+        verify(underlying);
+    }
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaAddressConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaAddressConverterTest.java
new file mode 100644
index 0000000..e93f140
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaAddressConverterTest.java
@@ -0,0 +1,54 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.Address;
+import org.apache.rave.portal.model.JpaAddress;
+import org.apache.rave.portal.model.impl.AddressImpl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+/**
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})
+public class JpaAddressConverterTest {
+
+    @Autowired
+    private JpaAddressConverter addressConverter;
+
+    @Test
+    public void noConversion() {
+        Address address = new JpaAddress();
+        assertThat(addressConverter.convert(address), is(sameInstance(address)));
+    }
+
+    @Test
+    public void nullConversion() {
+        Address address = null;
+        assertThat(addressConverter.convert(address), is(nullValue()));
+    }
+
+    @Test
+    public void newAddress() {
+        Address address = new AddressImpl();
+        address.setStreetAddress("1600 Pennsylvania Avenue");
+        address.setLocality("Washington DC");
+        address.setCountry("USA");
+        address.setRegion("Washington DC");
+        address.setPrimary(true);
+
+        JpaAddress converted = addressConverter.convert(address);
+        assertThat(converted, is(not(sameInstance(address))));
+        assertThat(converted, is(instanceOf(JpaAddress.class)));
+        assertThat(converted.getStreetAddress(), is(equalTo(address.getStreetAddress())));
+        assertThat(converted.getLocality(), is(equalTo(address.getLocality())));
+        assertThat(converted.getCountry(), is(equalTo(address.getCountry())));
+        assertThat(converted.getRegion(), is(equalTo(address.getRegion())));
+        assertThat(converted.getPrimary(), is(true));
+    }
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaApplicationDataConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaApplicationDataConverterTest.java
new file mode 100644
index 0000000..dc4ec99
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaApplicationDataConverterTest.java
@@ -0,0 +1,71 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.conversion;

+

+import org.apache.rave.portal.model.ApplicationData;

+import org.apache.rave.portal.model.JpaApplicationData;

+import org.apache.rave.portal.model.impl.ApplicationDataImpl;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+

+import java.util.HashMap;

+

+import static org.hamcrest.CoreMatchers.*;

+import static org.junit.Assert.assertThat;

+

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaApplicationDataConverterTest {

+

+    @Autowired

+    private JpaApplicationDataConverter applicationDataConverter;

+

+    @Test

+    public void noConversion() {

+        ApplicationData applicationData = new JpaApplicationData();

+        assertThat(applicationDataConverter.convert(applicationData), is(sameInstance(applicationData)));

+    }

+

+    @Test

+    public void nullConversion() {

+        ApplicationData applicationData = null;

+        assertThat(applicationDataConverter.convert(applicationData), is(nullValue()));

+    }

+

+    @Test

+    public void newApplicationData() {

+        ApplicationData applicationData = new ApplicationDataImpl();

+        applicationData.setId(1L);

+        applicationData.setAppUrl("url");

+        applicationData.setData(new HashMap<String, String>());

+        applicationData.setUserId("userid");

+

+        JpaApplicationData converted = applicationDataConverter.convert(applicationData);

+        assertThat(converted, is(not(sameInstance(applicationData))));

+        assertThat(converted, is(instanceOf(JpaApplicationData.class)));

+        assertThat(converted.getId(), is(equalTo(applicationData.getId())));

+        assertThat(converted.getEntityId(), is(equalTo(applicationData.getId())));

+        assertThat(converted.getAppUrl(), is(equalTo(applicationData.getAppUrl())));

+        assertThat(converted.getData(), is(equalTo(applicationData.getData())));

+        assertThat(converted.getUserId(), is(equalTo(applicationData.getUserId())));

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaAuthorityConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaAuthorityConverterTest.java
new file mode 100644
index 0000000..bd4ac7e
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaAuthorityConverterTest.java
@@ -0,0 +1,59 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaAuthority;
+import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.impl.AuthorityImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaAuthorityConverterTest {
+
+    @Autowired
+    JpaAuthorityConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaAuthority template = new JpaAuthority();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        Authority template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        Authority template = new AuthorityImpl();
+        template.setAuthority("FOO");
+        template.setDefaultForNewUser(true);
+        template.addUser(new UserImpl(42L));
+
+        JpaAuthority jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaAuthority.class)));
+        assertThat(jpaTemplate.getAuthority(), is(equalTo(template.getAuthority())));
+        assertThat(jpaTemplate.isDefaultForNewUser(), is(equalTo(template.isDefaultForNewUser())));
+        assertThat(jpaTemplate.getUsers().iterator().next().getId(), is(equalTo(template.getUsers().iterator().next().getId())));
+
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaCategoryConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaCategoryConverterTest.java
new file mode 100644
index 0000000..d6e8ecb
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaCategoryConverterTest.java
@@ -0,0 +1,77 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.conversion;

+

+import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.CategoryImpl;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+

+import java.util.ArrayList;

+import java.util.Date;

+

+import static org.hamcrest.CoreMatchers.*;

+import static org.junit.Assert.assertThat;

+

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaCategoryConverterTest {

+

+    @Autowired

+    private JpaCategoryConverter categoryConverter;

+

+    @Test

+    public void noConversion() {

+        Category category = new JpaCategory();

+        assertThat(categoryConverter.convert(category), is(sameInstance(category)));

+    }

+

+    @Test

+    public void nullConversion() {

+        Category category = null;

+        assertThat(categoryConverter.convert(category), is(nullValue()));

+    }

+

+    @Test

+    public void newCategory() {

+        Category category = new CategoryImpl();

+        category.setCreatedDate(new Date());

+        category.setId(9L);

+        category.setLastModifiedDate(new Date());

+        category.setText("hello");

+        category.setCreatedUser(new JpaUser(1L));

+        category.setLastModifiedUser(new JpaUser(1L));

+        category.setWidgets(new ArrayList<Widget>());

+

+        JpaCategory converted = categoryConverter.convert(category);

+        assertThat(converted, is(not(sameInstance(category))));

+        assertThat(converted, is(instanceOf(JpaCategory.class)));

+        assertThat(converted.getCreatedDate(), is(equalTo(category.getCreatedDate())));

+        assertThat(converted.getCreatedUser(), is(equalTo(category.getCreatedUser())));

+        assertThat(converted.getEntityId(), is(equalTo(category.getId())));

+        assertThat(converted.getId(), is(equalTo(category.getId())));

+        assertThat(converted.getLastModifiedDate(), is(equalTo(category.getLastModifiedDate())));

+        assertThat(converted.getLastModifiedUser(), is(equalTo(category.getLastModifiedUser())));

+        assertThat(converted.getText(), is(equalTo(category.getText())));

+        assertThat(converted.getWidgets(), is(equalTo(category.getWidgets())));

+    }

+}

diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaConverterTest.java
new file mode 100644
index 0000000..8fe49fd
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaConverterTest.java
@@ -0,0 +1,94 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.model.ModelConverter;
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.AddressImpl;
+import org.apache.rave.portal.model.impl.GroupImpl;
+import org.apache.rave.portal.model.impl.PersonImpl;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})
+public class JpaConverterTest {
+
+    private List<ModelConverter> converters;
+
+    //Inject the list of converters from the context to work around any issues that arise during testing
+    @Autowired
+    private List<ModelConverter> originalConverters;
+
+    @Before
+    public void setup() throws NoSuchFieldException, IllegalAccessException {
+        ModelConverter personConverter = createMock(ModelConverter.class);
+        expect(personConverter.getSourceType()).andReturn(Person.class).anyTimes();
+        expect(personConverter.convert(isA(PersonImpl.class))).andReturn(new JpaPerson());
+        replay(personConverter);
+
+        ModelConverter addressConverter = createMock(ModelConverter.class);
+        expect(addressConverter.getSourceType()).andReturn(Address.class).anyTimes();
+        expect(addressConverter.convert(isA(AddressImpl.class))).andReturn(new JpaAddress());
+        replay(addressConverter);
+
+        ModelConverter pageLayoutConverter = createMock(ModelConverter.class);
+        expect(pageLayoutConverter.getSourceType()).andReturn(Address.class).anyTimes();
+        expect(pageLayoutConverter.convert(isA(PageLayout.class))).andReturn(new JpaPageLayout());
+        replay(pageLayoutConverter);
+
+        List<ModelConverter> converters = new ArrayList<ModelConverter>();
+        converters.add(personConverter);
+        converters.add(addressConverter);
+        this.converters = converters;
+        Field instance = JpaConverter.class.getDeclaredField("instance");
+        instance.setAccessible(true);
+        instance.set(null, null);
+    }
+
+    @After
+    public void tearDown() {
+        //Replace the instance of converters with the one from the context
+        new JpaConverter(originalConverters);
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void noInstance() {
+        JpaConverter.getInstance();
+    }
+
+    @Test
+    public void converts() {
+        new JpaConverter(converters);
+        assertThat(JpaConverter.getInstance().convert(new AddressImpl(), Address.class), is(instanceOf(JpaAddress.class)));
+        assertThat(JpaConverter.getInstance().convert(new PersonImpl(), Person.class), is(instanceOf(JpaPerson.class)));
+
+    }
+
+    @Test
+    public void getMap() {
+        new JpaConverter(converters);
+        ModelConverter<Address, JpaAddress> converter = JpaConverter.getInstance().getConverter(Address.class);
+        assertThat(converter, is(not(nullValue())));
+        assertThat(converter.getSourceType(), is(equalTo(Address.class)));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void notFound() {
+        new JpaConverter(converters);
+        JpaConverter.getInstance().convert(new GroupImpl(), Group.class);
+    }
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaGroupConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaGroupConverterTest.java
new file mode 100644
index 0000000..472a21f
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaGroupConverterTest.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.Group;
+import org.apache.rave.portal.model.JpaGroup;
+import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.model.impl.GroupImpl;
+import org.apache.rave.portal.model.impl.PersonImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={"classpath:test-applicationContext.xml","classpath:test-dataContext.xml"} )
+public class JpaGroupConverterTest {
+
+    @Autowired
+    JpaGroupConverter converter;
+
+    private Group group;
+    private String description = "Test Group";
+    private Long entityId = Long.valueOf(400);
+    private String title = "GroupTitle";
+    private Person owner = null;
+    private List<Person> members = null;
+
+    private String ownerDisplayName = "Bob";
+    private String ownerGivenName = "Smith";
+
+    @Before
+    public void setup() {
+        members = new ArrayList<Person>();
+        owner = new PersonImpl();
+        owner.setDisplayName(ownerDisplayName);
+        owner.setGivenName(ownerGivenName);
+        members.add(owner);
+
+        group = new GroupImpl();
+        group.setDescription(description);
+        group.setTitle(title);
+        group.setOwner(owner);
+        group.setMembers(members);
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaGroup group = new JpaGroup();
+        assertThat(converter.convert(group), is(sameInstance(group)));
+    }
+
+    @Test
+    public void nullConversion() {
+        Group category = null;
+        assertThat(converter.convert(category), is(nullValue()));
+    }
+
+    @Test
+    public void testConvertGroupToJpaGroup() {
+        JpaGroup jpaGroup = converter.convert(group);
+
+        assertThat(jpaGroup, is(not(sameInstance(group))));
+        assertThat(jpaGroup, is(instanceOf(JpaGroup.class)));
+        assertEquals(description, jpaGroup.getDescription());
+        assertEquals(title, jpaGroup.getTitle());
+        assertEquals(owner.getDisplayName(), jpaGroup.getOwner().getDisplayName());
+        assertEquals(members.size(), jpaGroup.getMembers().size());
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOAuthConsumerStoreConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOAuthConsumerStoreConverterTest.java
new file mode 100644
index 0000000..8f0d3aa
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOAuthConsumerStoreConverterTest.java
@@ -0,0 +1,59 @@
+package org.apache.rave.portal.model.conversion;

+

+import org.apache.rave.portal.model.JpaOAuthConsumerStore;

+import org.apache.rave.portal.model.OAuthConsumerStore;

+import org.apache.rave.portal.model.impl.OAuthConsumerStoreImpl;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+

+import static org.hamcrest.CoreMatchers.*;

+import static org.junit.Assert.assertThat;

+

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaOAuthConsumerStoreConverterTest {

+

+    @Autowired

+    private JpaOAuthConsumerStoreConverter oAuthConsumerStoreConverter;

+

+    @Test

+    public void noConversion() {

+        OAuthConsumerStore oAuthConsumerStore = new JpaOAuthConsumerStore();

+        assertThat(oAuthConsumerStoreConverter.convert(oAuthConsumerStore), is(sameInstance(oAuthConsumerStore)));

+    }

+

+    @Test

+    public void nullConversion() {

+        OAuthConsumerStore oAuthConsumerStore = null;

+        assertThat(oAuthConsumerStoreConverter.convert(oAuthConsumerStore), is(nullValue()));

+    }

+

+    @Test

+    public void newOAuthConsumerStore() {

+        OAuthConsumerStore oAuthConsumerStore = new OAuthConsumerStoreImpl();

+        oAuthConsumerStore.setId(1L);

+        oAuthConsumerStore.setServiceName("servicename");

+        oAuthConsumerStore.setCallbackUrl("callbackurl");

+        oAuthConsumerStore.setConsumerKey("key");

+        oAuthConsumerStore.setConsumerSecret("secret");

+        oAuthConsumerStore.setGadgetUri("gadgeturi");

+        oAuthConsumerStore.setKeyName("key");

+        oAuthConsumerStore.setKeyType(OAuthConsumerStore.KeyType.HMAC_SYMMETRIC);

+

+        JpaOAuthConsumerStore converted = oAuthConsumerStoreConverter.convert(oAuthConsumerStore);

+        assertThat(converted, is(not(sameInstance(oAuthConsumerStore))));

+        assertThat(converted, is(instanceOf(JpaOAuthConsumerStore.class)));

+        assertThat(converted.getId(), is(equalTo(oAuthConsumerStore.getId())));

+        assertThat(converted.getServiceName(), is(equalTo(oAuthConsumerStore.getServiceName())));

+        assertThat(converted.getCallbackUrl(), is(equalTo(oAuthConsumerStore.getCallbackUrl())));

+        assertThat(converted.getConsumerKey(), is(equalTo(oAuthConsumerStore.getConsumerKey())));

+        assertThat(converted.getConsumerSecret(), is(equalTo(oAuthConsumerStore.getConsumerSecret())));

+        assertThat(converted.getEntityId(), is(equalTo(oAuthConsumerStore.getId())));

+        assertThat(converted.getGadgetUri(), is(equalTo(oAuthConsumerStore.getGadgetUri())));

+        assertThat(converted.getKeyName(), is(equalTo(oAuthConsumerStore.getKeyName())));

+        assertThat(converted.getKeyType(), is(equalTo(oAuthConsumerStore.getKeyType())));

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOAuthTokenInfoConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOAuthTokenInfoConverterTest.java
new file mode 100644
index 0000000..f0cf080
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOAuthTokenInfoConverterTest.java
@@ -0,0 +1,81 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.conversion;

+

+import org.apache.rave.portal.model.JpaOAuthTokenInfo;

+import org.apache.rave.portal.model.OAuthTokenInfo;

+import org.apache.rave.portal.model.impl.OAuthTokenInfoImpl;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+

+import static org.hamcrest.CoreMatchers.*;

+import static org.junit.Assert.assertThat;

+

+

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaOAuthTokenInfoConverterTest {

+

+    @Autowired

+    private JpaOAuthTokenInfoConverter oAuthTokenInfoConverter;

+

+    @Test

+    public void noConversion() {

+        OAuthTokenInfo oAuthTokenInfo = new JpaOAuthTokenInfo();

+        assertThat(oAuthTokenInfoConverter.convert(oAuthTokenInfo), is(sameInstance(oAuthTokenInfo)));

+    }

+

+    @Test

+    public void nullConversion() {

+        OAuthTokenInfo oAuthTokenInfo = null;

+        assertThat(oAuthTokenInfoConverter.convert(oAuthTokenInfo), is(nullValue()));

+    }

+

+    @Test

+    public void newOAuthTokenInfo() {

+        OAuthTokenInfo oAuthTokenInfo = new OAuthTokenInfoImpl();

+        oAuthTokenInfo.setId(1L);

+        oAuthTokenInfo.setAccessToken("accesstoken");

+        oAuthTokenInfo.setAppUrl("appurl");

+        oAuthTokenInfo.setModuleId("moduleid");

+        oAuthTokenInfo.setServiceName("servicename");

+        oAuthTokenInfo.setSessionHandle("sessionhandle");

+        oAuthTokenInfo.setTokenExpireMillis(99L);

+        oAuthTokenInfo.setTokenName("tokenname");

+        oAuthTokenInfo.setTokenSecret("tokensecret");

+        oAuthTokenInfo.setUserId("userid");

+

+        JpaOAuthTokenInfo converted = oAuthTokenInfoConverter.convert(oAuthTokenInfo);

+        assertThat(converted, is(not(sameInstance(oAuthTokenInfo))));

+        assertThat(converted, is(instanceOf(JpaOAuthTokenInfo.class)));

+        assertThat(converted.getId(), is(equalTo(oAuthTokenInfo.getId())));

+        assertThat(converted.getAccessToken(), is(equalTo(oAuthTokenInfo.getAccessToken())));

+        assertThat(converted.getAppUrl(), is(equalTo(oAuthTokenInfo.getAppUrl())));

+        assertThat(converted.getModuleId(), is(equalTo(oAuthTokenInfo.getModuleId())));

+        assertThat(converted.getServiceName(), is(equalTo(oAuthTokenInfo.getServiceName())));

+        assertThat(converted.getSessionHandle(), is(equalTo(oAuthTokenInfo.getSessionHandle())));

+        assertThat(converted.getTokenExpireMillis(), is(equalTo(oAuthTokenInfo.getTokenExpireMillis())));

+        assertThat(converted.getTokenName(), is(equalTo(oAuthTokenInfo.getTokenName())));

+        assertThat(converted.getTokenSecret(), is(equalTo(oAuthTokenInfo.getTokenSecret())));

+        assertThat(converted.getUserId(), is(equalTo(oAuthTokenInfo.getUserId())));

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOrganizationConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOrganizationConverterTest.java
new file mode 100644
index 0000000..1930e3c
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaOrganizationConverterTest.java
@@ -0,0 +1,76 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaOrganization;
+import org.apache.rave.portal.model.Organization;
+import org.apache.rave.portal.model.impl.AddressImpl;
+import org.apache.rave.portal.model.impl.OrganizationImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.Date;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaOrganizationConverterTest {
+
+    @Autowired
+    JpaOrganizationConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaOrganization template = new JpaOrganization();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        Organization template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        Organization template = new OrganizationImpl();
+        template.setAddress(new AddressImpl("123 Sesame Street"));
+        template.setDescription("TEST_A");
+        template.setEndDate(new Date());
+        template.setField("TEST_B");
+        template.setName("TEST_C");
+        template.setStartDate(new Date());
+        template.setSubField("TEST_D");
+        template.setTitle("TEST_E");
+        template.setWebpage("TEST_F");
+        template.setQualifier("TEST_G");
+        template.setPrimary(true    );
+
+        JpaOrganization jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaOrganization.class)));
+        assertThat(jpaTemplate.getAddress().getStreetAddress(), is(equalTo(template.getAddress().getStreetAddress())));
+        assertThat(jpaTemplate.getDescription(), is(equalTo(template.getDescription())));
+        assertThat(jpaTemplate.getEndDate(), is(equalTo(template.getEndDate())));
+        assertThat(jpaTemplate.getField(), is(equalTo(template.getField())));
+        assertThat(jpaTemplate.getName(), is(equalTo(template.getName())));
+        assertThat(jpaTemplate.getStartDate(), is(equalTo(template.getStartDate())));
+        assertThat(jpaTemplate.getSubField(), is(equalTo(template.getSubField())));
+        assertThat(jpaTemplate.getTitle(), is(equalTo(template.getTitle())));
+        assertThat(jpaTemplate.getWebpage(), is(equalTo(template.getWebpage())));
+        assertThat(jpaTemplate.getQualifier(), is(equalTo(template.getQualifier())));
+        assertThat(jpaTemplate.getPrimary(), is(equalTo(template.getPrimary())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java
new file mode 100644
index 0000000..1957de1
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageConverterTest.java
@@ -0,0 +1,80 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.conversion;

+

+import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.PageImpl;

+import org.apache.rave.portal.model.impl.PageLayoutImpl;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+

+import java.util.ArrayList;

+

+import static org.hamcrest.CoreMatchers.*;

+import static org.junit.Assert.assertThat;

+

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaPageConverterTest {

+

+    @Autowired

+    private JpaPageConverter pageConverter;

+

+    @Test

+    public void noConversion() {

+        Page page = new JpaPage();

+        assertThat(pageConverter.convert(page), is(sameInstance(page)));

+    }

+

+    @Test

+    public void nullConversion() {

+        Page page = null;

+        assertThat(pageConverter.convert(page), is(nullValue()));

+    }

+

+    @Test

+    public void newPage() {

+        Page page = new PageImpl();

+        page.setId(1L);

+        page.setMembers(new ArrayList<PageUser>());

+        page.setName("name");

+        page.setOwner(new JpaUser());

+        page.setPageLayout(new PageLayoutImpl());

+        page.setPageType(PageType.USER);

+        page.setParentPage(new PageImpl(1L));

+        page.setRegions(new ArrayList<Region>());

+        page.setSubPages(new ArrayList<Page>());

+

+        JpaPage converted = pageConverter.convert(page);

+        assertThat(converted, is(not(sameInstance(page))));

+        assertThat(converted, is(instanceOf(JpaPage.class)));

+        assertThat(converted.getId(), is(equalTo(page.getId())));

+        assertThat(converted.getParentPage().getId(), is(equalTo(page.getParentPage().getId())));

+        assertThat(converted.getRegions(), is(equalTo(page.getRegions())));

+        assertThat(converted.getMembers(), is(equalTo(page.getMembers())));

+        assertThat(converted.getName(), is(equalTo(page.getName())));

+        assertThat(converted.getOwner(), is(equalTo(page.getOwner())));

+        assertThat(converted.getPageLayout().getCode(), is(equalTo(page.getPageLayout().getCode())));

+        assertThat(converted.getPageType(), is(equalTo(page.getPageType())));

+        assertThat(converted.getSubPages(), is(equalTo(page.getSubPages())));

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateConverterTest.java
new file mode 100644
index 0000000..db212aa
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateConverterTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.PageLayoutImpl;
+import org.apache.rave.portal.model.impl.PageTemplateImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaPageTemplateConverterTest {
+
+    @Autowired
+    JpaPageTemplateConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaPageTemplate template = new JpaPageTemplate();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        PageTemplate template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        PageTemplate template = new PageTemplateImpl();
+        template.setName("name");
+        template.setSubPageTemplates(new ArrayList<PageTemplate>());
+        template.setDefaultTemplate(true);
+        template.setRenderSequence(1);
+        template.setPageTemplateRegions(new ArrayList<PageTemplateRegion>());
+        template.setPageLayout(new PageLayoutImpl());
+        template.setParentPageTemplate(new PageTemplateImpl());
+        template.setDescription("Description");
+        template.setPageType(PageType.USER);
+
+        JpaPageTemplate jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaPageTemplate.class)));
+        assertThat(jpaTemplate.getId(), is(equalTo(template.getId())));
+        assertThat(jpaTemplate.getPageType(), is(equalTo(template.getPageType())));
+        assertThat(jpaTemplate.getName(), is(equalTo(template.getName())));
+        assertThat(jpaTemplate.getDescription(), is(equalTo(template.getDescription())));
+        assertThat(jpaTemplate.getParentPageTemplate(), is(instanceOf(JpaPageTemplate.class)));
+        assertThat(jpaTemplate.getPageLayout(), is(instanceOf(JpaPageLayout.class)));
+        assertThat(jpaTemplate.getPageTemplateRegions(), is(equalTo(template.getPageTemplateRegions())));
+        assertThat(jpaTemplate.getRenderSequence(), is(equalTo(template.getRenderSequence())));
+        assertThat(jpaTemplate.isDefaultTemplate(), is(equalTo(template.isDefaultTemplate())));
+        assertThat(jpaTemplate.getSubPageTemplates(), is(equalTo(template.getSubPageTemplates())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateRegionConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateRegionConverterTest.java
new file mode 100644
index 0000000..d988d1a
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateRegionConverterTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaPageTemplate;
+import org.apache.rave.portal.model.JpaPageTemplateRegion;
+import org.apache.rave.portal.model.PageTemplateRegion;
+import org.apache.rave.portal.model.PageTemplateWidget;
+import org.apache.rave.portal.model.impl.PageTemplateImpl;
+import org.apache.rave.portal.model.impl.PageTemplateRegionImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaPageTemplateRegionConverterTest {
+
+    @Autowired
+    JpaPageTemplateRegionConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaPageTemplateRegion template = new JpaPageTemplateRegion();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        PageTemplateRegion template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        PageTemplateRegion template = new PageTemplateRegionImpl();
+        template.setRenderSequence(1);
+        template.setPageTemplateWidgets(new ArrayList<PageTemplateWidget>());
+        template.setPageTemplate(new PageTemplateImpl());
+        template.setLocked(true);
+
+        JpaPageTemplateRegion jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaPageTemplateRegion.class)));
+        assertThat(jpaTemplate.getRenderSequence(), is(equalTo(template.getRenderSequence())));
+        assertThat(jpaTemplate.getPageTemplate(), is(instanceOf(JpaPageTemplate.class)));
+        assertThat(jpaTemplate.getPageTemplateWidgets(), is(equalTo(template.getPageTemplateWidgets())));
+        assertThat(jpaTemplate.isLocked(), is(equalTo(template.isLocked())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateWidgetConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateWidgetConverterTest.java
new file mode 100644
index 0000000..ffc4d3c
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPageTemplateWidgetConverterTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.PageTemplateRegionImpl;
+import org.apache.rave.portal.model.impl.PageTemplateWidgetImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaPageTemplateWidgetConverterTest {
+
+    @Autowired
+    JpaPageTemplateWidgetConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaPageTemplateWidget template = new JpaPageTemplateWidget();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        PageTemplateWidget template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        JpaWidget widget = new JpaWidget();
+        PageTemplateWidget template = new PageTemplateWidgetImpl();
+        template.setLocked(true);
+        template.setHideChrome(true);
+        template.setPageTemplateRegion(new PageTemplateRegionImpl());
+        template.setRenderSeq(1);
+        template.setWidget(widget);
+
+        JpaPageTemplateWidget jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaPageTemplateWidget.class)));
+        assertThat(jpaTemplate.isLocked(), is(equalTo(template.isLocked())));
+        assertThat(jpaTemplate.getPageTemplateRegion(), is(instanceOf(JpaPageTemplateRegion.class)));
+        assertThat(jpaTemplate.getRenderSeq(), is(equalTo(template.getRenderSeq())));
+        assertThat(jpaTemplate.getWidget(), is(equalTo(template.getWidget())));
+        assertThat(jpaTemplate.isLocked(), is(equalTo(template.isLocked())));
+        assertThat(jpaTemplate.isHideChrome(), is(equalTo(template.isHideChrome())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java
new file mode 100644
index 0000000..e19cc2b
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonConverterTest.java
@@ -0,0 +1,82 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.PersonImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaPersonConverterTest {
+
+    @Autowired
+    JpaPersonConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaPerson template = new JpaPerson();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        Person template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        Person template = new PersonImpl();
+        template.setUsername("TEST_A");
+        template.setEmail("TEST_B");
+        template.setDisplayName("TEST_C");
+        template.setAdditionalName("TEST_D");
+        template.setFamilyName("TEST_E");
+        template.setGivenName("TEST_F");
+        template.setHonorificPrefix("TEST_G");
+        template.setHonorificSuffix("TEST_H");
+        template.setPreferredName("TEST_I");
+        template.setAboutMe("TEST_J");
+        template.setStatus("TEST_K");
+        template.setAddresses(new ArrayList<Address>());
+        template.setOrganizations(new ArrayList<Organization>());
+        template.setProperties(new ArrayList<PersonProperty>());
+        template.setFriends(new ArrayList<Person>());
+
+        JpaPerson jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaPerson.class)));
+        assertThat(jpaTemplate.getUsername(), is(equalTo(template.getUsername())));
+        assertThat(jpaTemplate.getEmail(), is(equalTo(template.getEmail())));
+        assertThat(jpaTemplate.getDisplayName(), is(equalTo(template.getDisplayName())));
+        assertThat(jpaTemplate.getUsername(), is(equalTo(template.getUsername())));
+        assertThat(jpaTemplate.getFamilyName(), is(equalTo(template.getFamilyName())));
+        assertThat(jpaTemplate.getGivenName(), is(equalTo(template.getGivenName())));
+        assertThat(jpaTemplate.getHonorificPrefix(), is(equalTo(template.getHonorificPrefix())));
+        assertThat(jpaTemplate.getHonorificSuffix(), is(equalTo(template.getHonorificSuffix())));
+        assertThat(jpaTemplate.getPreferredName(), is(equalTo(template.getPreferredName())));
+        assertThat(jpaTemplate.getAboutMe(), is(equalTo(template.getAboutMe())));
+        assertThat(jpaTemplate.getStatus(), is(equalTo(template.getStatus())));
+        assertThat(jpaTemplate.getAddresses(), is(equalTo(template.getAddresses())));
+        assertThat(jpaTemplate.getOrganizations(), is(equalTo(template.getOrganizations())));
+        assertThat(jpaTemplate.getProperties(), is(equalTo(template.getProperties())));
+        assertThat(jpaTemplate.getFriends(), is(equalTo(template.getFriends())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonPropertyConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonPropertyConverterTest.java
new file mode 100644
index 0000000..7ea8ad9
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPersonPropertyConverterTest.java
@@ -0,0 +1,64 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaPersonProperty;
+import org.apache.rave.portal.model.PersonProperty;
+import org.apache.rave.portal.model.impl.PersonPropertyImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaPersonPropertyConverterTest {
+
+    @Autowired
+    JpaPersonPropertyConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaPersonProperty template = new JpaPersonProperty();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        PersonProperty template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        PersonProperty template = new PersonPropertyImpl();
+        template.setId(42L);
+        template.setType("TEST_A");
+        template.setValue("TEST_B");
+        template.setQualifier("TEST_C");
+        template.setExtendedValue("TEST_D");
+        template.setPrimary(true);
+
+        JpaPersonProperty jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaPersonProperty.class)));
+        assertThat(jpaTemplate.getId(), is(equalTo(template.getId())));
+        assertThat(jpaTemplate.getType(), is(equalTo(template.getType())));
+        assertThat(jpaTemplate.getValue(), is(equalTo(template.getValue())));
+        assertThat(jpaTemplate.getQualifier(), is(equalTo(template.getQualifier())));
+        assertThat(jpaTemplate.getExtendedValue(), is(equalTo(template.getExtendedValue())));
+        assertThat(jpaTemplate.getPrimary(), is(equalTo(template.getPrimary())));
+        
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPortalPreferenceConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPortalPreferenceConverterTest.java
new file mode 100644
index 0000000..0dc1116
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaPortalPreferenceConverterTest.java
@@ -0,0 +1,55 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaPortalPreference;
+import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.impl.PortalPreferenceImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaPortalPreferenceConverterTest {
+
+    @Autowired
+    JpaPortalPreferenceConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaPortalPreference template = new JpaPortalPreference();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        PortalPreference template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        PortalPreference template = new PortalPreferenceImpl();
+        template.setKey("KEY");
+        template.setValue("VALUE");
+
+        JpaPortalPreference jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaPortalPreference.class)));
+        assertThat(jpaTemplate.getKey(), is(equalTo(template.getKey())));
+        assertThat(jpaTemplate.getValue(), is(equalTo(template.getValue())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionConverterTest.java
new file mode 100644
index 0000000..1926374
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionConverterTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.PageImpl;
+import org.apache.rave.portal.model.impl.RegionImpl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})
+public class JpaRegionConverterTest {
+
+    @Autowired
+    private JpaRegionConverter regionConverter;
+
+    @Test
+    public void noConversion() {
+        Region region = new JpaRegion();
+        assertThat(regionConverter.convert(region), is(sameInstance(region)));
+    }
+
+    @Test
+    public void nullConversion() {
+        Region template = null;
+        assertThat(regionConverter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void newRegion() {
+        Region region = new RegionImpl();
+        region.setId(9L);
+        region.setLocked(false);
+        region.setPage(new JpaPage());
+        region.setRegionWidgets(new ArrayList<RegionWidget>());
+        region.setRenderOrder(9);
+
+        JpaRegion converted = regionConverter.convert(region);
+        assertThat(converted, is(not(sameInstance(region))));
+        assertThat(converted, is(instanceOf(JpaRegion.class)));
+        assertThat(converted.getRegionWidgets(), is(equalTo(region.getRegionWidgets())));
+        assertThat(converted.getEntityId(), is(equalTo(region.getId())));
+        assertThat(converted.getId(), is(equalTo(region.getId())));
+        assertThat(converted.getPage(), is(instanceOf(Page.class)));
+        assertThat(converted.getRenderOrder(), is(equalTo(region.getRenderOrder())));
+        assertThat(converted.isLocked(), is(equalTo(region.isLocked())));
+    }
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetConverterTest.java
new file mode 100644
index 0000000..0c4f5d7
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetConverterTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.RegionImpl;
+import org.apache.rave.portal.model.impl.RegionWidgetImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})
+public class JpaRegionWidgetConverterTest {
+
+    @Autowired
+    private JpaRegionWidgetConverter regionWidgetConverter;
+
+    @Test
+    public void noConversion() {
+        RegionWidget rw = new JpaRegionWidget();
+        assertThat(regionWidgetConverter.convert(rw), is(sameInstance(rw)));
+    }
+
+    @Test
+    public void nullConversion() {
+        RegionWidget template = null;
+        assertThat(regionWidgetConverter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void newRegion() {
+        RegionWidget rw = new RegionWidgetImpl();
+        rw.setId(9L);
+        rw.setLocked(false);
+        rw.setCollapsed(false);
+        rw.setHideChrome(true);
+        rw.setRenderOrder(9);
+        rw.setPreferences(new ArrayList<RegionWidgetPreference>());
+        rw.setRegion(new RegionImpl());
+        rw.setRenderPosition("last");
+        rw.setWidget(new WidgetImpl());
+
+        JpaRegionWidget converted = regionWidgetConverter.convert(rw);
+        assertThat(converted, is(not(sameInstance(rw))));
+        assertThat(converted, is(instanceOf(JpaRegionWidget.class)));
+        assertThat(converted.getPreferences(), is(equalTo(rw.getPreferences())));
+        assertThat(converted.getEntityId(), is(equalTo(rw.getId())));
+        assertThat(converted.getId(), is(equalTo(rw.getId())));
+        assertThat(converted.isCollapsed(), is(equalTo(rw.isCollapsed())));
+        assertThat(converted.getRenderOrder(), is(equalTo(rw.getRenderOrder())));
+        assertThat(converted.isLocked(), is(equalTo(rw.isLocked())));
+        assertThat(converted.isHideChrome(), is(equalTo(rw.isHideChrome())));
+        assertThat(converted.getRegion(), is(instanceOf(JpaRegion.class)));
+        assertThat(converted.getRenderPosition(), is(equalTo(rw.getRenderPosition())));
+        assertThat(converted.getWidget(), is(instanceOf(JpaWidget.class)));
+    }
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetPreferenceConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetPreferenceConverterTest.java
new file mode 100644
index 0000000..7910454
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaRegionWidgetPreferenceConverterTest.java
@@ -0,0 +1,57 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaRegionWidgetPreference;
+import org.apache.rave.portal.model.RegionWidgetPreference;
+import org.apache.rave.portal.model.impl.RegionWidgetPreferenceImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaRegionWidgetPreferenceConverterTest {
+
+    @Autowired
+    JpaRegionWidgetPreferenceConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaRegionWidgetPreference template = new JpaRegionWidgetPreference();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        RegionWidgetPreference template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        RegionWidgetPreference template = new RegionWidgetPreferenceImpl();
+        template.setName("TEST_A");
+        template.setRegionWidgetId(42L);
+        template.setValue("TEST_B");
+
+        JpaRegionWidgetPreference jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaRegionWidgetPreference.class)));
+        assertThat(jpaTemplate.getName(), is(equalTo(template.getName())));
+        assertThat(jpaTemplate.getRegionWidgetId(), is(equalTo(template.getRegionWidgetId())));
+        assertThat(jpaTemplate.getValue(), is(equalTo(template.getValue())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaTagConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaTagConverterTest.java
new file mode 100644
index 0000000..7cf068b
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaTagConverterTest.java
@@ -0,0 +1,46 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaTag;
+import org.apache.rave.portal.model.impl.TagImpl;
+import org.apache.rave.portal.model.WidgetTag;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})
+public class JpaTagConverterTest {
+    
+    @Autowired
+    JpaTagConverter jpaTagConverter;
+
+    @Test
+    public void convert_valid_tagImpl(){
+        TagImpl tag = new TagImpl("blazer", new ArrayList<WidgetTag>());
+        JpaTag jpaTag = jpaTagConverter.convert(tag);
+        assertNotNull(jpaTag);
+        assertEquals(tag.getKeyword(), jpaTag.getKeyword()); 
+        assertEquals(tag.getWidgets().size(), jpaTag.getWidgets().size());
+    }
+
+
+    @Test
+    public void convert_valid_jpaTag(){
+        JpaTag tag = new JpaTag();
+        tag.setKeyword("blazer");
+        tag.setWidgets(new ArrayList<WidgetTag>());
+        tag.setEntityId(387L);
+        JpaTag jpaTag = jpaTagConverter.convert(tag);
+        assertNotNull(jpaTag);
+        assertSame(tag, jpaTag);
+    }
+    
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaUserConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaUserConverterTest.java
new file mode 100644
index 0000000..2eff956
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaUserConverterTest.java
@@ -0,0 +1,110 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.AuthorityImpl;
+import org.apache.rave.portal.model.impl.PageLayoutImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+import java.util.Date;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaUserConverterTest {
+
+    @Autowired
+    JpaUserConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaUser template = new JpaUser();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        User template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        User template = new UserImpl();
+        template.setUsername("TEST_A");
+        template.setEmail("TEST_B");
+        template.setDisplayName("TEST_C");
+        template.setAdditionalName("TEST_D");
+        template.setFamilyName("TEST_E");
+        template.setGivenName("TEST_F");
+        template.setHonorificPrefix("TEST_G");
+        template.setHonorificSuffix("TEST_H");
+        template.setPreferredName("TEST_I");
+        template.setAboutMe("TEST_J");
+        template.setStatus("TEST_K");
+        template.setAddresses(new ArrayList<Address>());
+        template.setOrganizations(new ArrayList<Organization>());
+        template.setProperties(new ArrayList<PersonProperty>());
+        template.setFriends(new ArrayList<Person>());
+        template.setPassword("TEST_L");
+        template.setConfirmPassword("TEST_M");
+        template.setDefaultPageLayout(new PageLayoutImpl("CODE"));
+        template.setDefaultPageLayoutCode("TEST_N");
+        template.setEnabled(true);
+        template.setExpired(true);
+        template.setLocked(true);
+        template.setOpenId("TEST_O");
+        template.setForgotPasswordHash("TEST_P");
+        template.setForgotPasswordTime(new Date());
+        template.addAuthority(new AuthorityImpl(new SimpleGrantedAuthority("HOO")));
+
+
+        JpaUser jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaUser.class)));
+        assertThat(jpaTemplate.getId(), is(equalTo(template.getId())));
+        assertThat(jpaTemplate.getUsername(), is(equalTo(template.getUsername())));
+        assertThat(jpaTemplate.getEmail(), is(equalTo(template.getEmail())));
+        assertThat(jpaTemplate.getDisplayName(), is(equalTo(template.getDisplayName())));
+        assertThat(jpaTemplate.getUsername(), is(equalTo(template.getUsername())));
+        assertThat(jpaTemplate.getFamilyName(), is(equalTo(template.getFamilyName())));
+        assertThat(jpaTemplate.getGivenName(), is(equalTo(template.getGivenName())));
+        assertThat(jpaTemplate.getHonorificPrefix(), is(equalTo(template.getHonorificPrefix())));
+        assertThat(jpaTemplate.getHonorificSuffix(), is(equalTo(template.getHonorificSuffix())));
+        assertThat(jpaTemplate.getPreferredName(), is(equalTo(template.getPreferredName())));
+        assertThat(jpaTemplate.getAboutMe(), is(equalTo(template.getAboutMe())));
+        assertThat(jpaTemplate.getStatus(), is(equalTo(template.getStatus())));
+        assertThat(jpaTemplate.getAddresses(), is(equalTo(template.getAddresses())));
+        assertThat(jpaTemplate.getOrganizations(), is(equalTo(template.getOrganizations())));
+        assertThat(jpaTemplate.getProperties(), is(equalTo(template.getProperties())));
+        assertThat(jpaTemplate.getFriends(), is(equalTo(template.getFriends())));
+        assertThat(jpaTemplate.getPassword(), is(equalTo(template.getPassword())));
+        assertThat(jpaTemplate.getConfirmPassword(), is(equalTo(template.getConfirmPassword())));
+        assertThat(jpaTemplate.getDefaultPageLayout().getCode(), is(equalTo(template.getDefaultPageLayout().getCode())));
+        assertThat(jpaTemplate.getDefaultPageLayoutCode(), is(equalTo(template.getDefaultPageLayoutCode())));
+        assertThat(jpaTemplate.isEnabled(), is(equalTo(template.isEnabled())));
+        assertThat(jpaTemplate.isExpired(), is(equalTo(template.isExpired())));
+        assertThat(jpaTemplate.isLocked(), is(equalTo(template.isLocked())));
+        assertThat(jpaTemplate.getOpenId(), is(equalTo(template.getOpenId())));
+        assertThat(jpaTemplate.getForgotPasswordHash(), is(equalTo(template.getForgotPasswordHash())));
+        assertThat(jpaTemplate.getForgotPasswordTime(), is(equalTo(template.getForgotPasswordTime())));
+        assertThat(jpaTemplate.getAuthorities().iterator().next().getAuthority(), is(equalTo(template.getAuthorities().iterator().next().getAuthority())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetCommentConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetCommentConverterTest.java
new file mode 100644
index 0000000..e41399e
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetCommentConverterTest.java
@@ -0,0 +1,77 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.model.conversion;

+

+import org.apache.rave.portal.model.JpaUser;

+import org.apache.rave.portal.model.JpaWidgetComment;

+import org.apache.rave.portal.model.WidgetComment;

+import org.apache.rave.portal.model.impl.WidgetCommentImpl;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+

+import java.util.Date;

+

+import static org.hamcrest.CoreMatchers.*;

+import static org.junit.Assert.assertThat;

+

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaWidgetCommentConverterTest {

+

+    @Autowired

+    private JpaWidgetCommentConverter widgetCommentConverter;

+

+    @Test

+    public void noConversion() {

+        WidgetComment comment = new JpaWidgetComment();

+        assertThat(widgetCommentConverter.convert(comment), is(sameInstance(comment)));

+    }

+

+    @Test

+    public void nullConversion() {

+        WidgetComment template = null;

+        assertThat(widgetCommentConverter.convert(template), is(nullValue()));

+    }

+

+

+    @Test

+    public void newComment() {

+        WidgetComment comment = new WidgetCommentImpl();

+        comment.setCreatedDate(new Date());

+        comment.setId(9L);

+        comment.setLastModifiedDate(new Date());

+        comment.setText("hello");

+        comment.setUser(new JpaUser(1L));

+        comment.setWidgetId(9L);

+

+        JpaWidgetComment converted = widgetCommentConverter.convert(comment);

+        assertThat(converted, is(not(sameInstance(comment))));

+        assertThat(converted, is(instanceOf(JpaWidgetComment.class)));

+        assertThat(converted.getCreatedDate(), is(equalTo(comment.getCreatedDate())));

+        assertThat(converted.getEntityId(), is(equalTo(comment.getId())));

+        assertThat(converted.getId(), is(equalTo(comment.getId())));

+        assertThat(converted.getLastModifiedDate(), is(equalTo(comment.getLastModifiedDate())));

+        assertThat(converted.getText(), is(equalTo(comment.getText())));

+        assertThat(converted.getUser(), is(equalTo(comment.getUser())));

+        assertThat(converted.getWidgetId(), is(equalTo(comment.getWidgetId())));

+    }

+}
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetConverterTest.java
new file mode 100644
index 0000000..bbc0692
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetConverterTest.java
@@ -0,0 +1,91 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaWidgetConverterTest {
+
+    @Autowired
+    JpaWidgetConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaWidget template = new JpaWidget();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        Widget template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        WidgetImpl template = new WidgetImpl();
+        template.setId(42L);
+        template.setUrl("TEST_A");
+        template.setType("TEST_B");
+        template.setTitle("TEST_C");
+        template.setTitleUrl("TEST_D");
+        template.setUrl("TEST_E");
+        template.setThumbnailUrl("TEST_F");
+        template.setScreenshotUrl("TEST_G");
+        template.setAuthor("TEST_H");
+        template.setAuthorEmail("TEST_I");
+        template.setDescription("TEST_J");
+        template.setWidgetStatus(WidgetStatus.PUBLISHED);
+        template.setComments(new ArrayList<WidgetComment>());
+        template.setOwner(new UserImpl(24L));
+        template.setDisableRendering(true);
+        template.setRatings(new ArrayList<WidgetRating>());
+        template.setTags(new ArrayList<WidgetTag>());
+        template.setCategories(new ArrayList<Category>());
+        template.setFeatured(true);
+
+        Widget jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance((Widget)template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaWidget.class)));
+        assertThat(jpaTemplate.getId(), is(equalTo(template.getId())));
+        assertThat(jpaTemplate.getUrl(), is(equalTo(template.getUrl())));
+        assertThat(jpaTemplate.getType(), is(equalTo(template.getType())));
+        assertThat(jpaTemplate.getTitle(), is(equalTo(template.getTitle())));
+        assertThat(jpaTemplate.getTitleUrl(), is(equalTo(template.getTitleUrl())));
+        assertThat(jpaTemplate.getUrl(), is(equalTo(template.getUrl())));
+        assertThat(jpaTemplate.getThumbnailUrl(), is(equalTo(template.getThumbnailUrl())));
+        assertThat(jpaTemplate.getScreenshotUrl(), is(equalTo(template.getScreenshotUrl())));
+        assertThat(jpaTemplate.getAuthor(), is(equalTo(template.getAuthor())));
+        assertThat(jpaTemplate.getAuthorEmail(), is(equalTo(template.getAuthorEmail())));
+        assertThat(jpaTemplate.getDescription(), is(equalTo(template.getDescription())));
+        assertThat(jpaTemplate.getWidgetStatus(), is(equalTo(template.getWidgetStatus())));
+        assertThat(jpaTemplate.getComments(), is(equalTo(template.getComments())));
+        assertThat(jpaTemplate.getOwner().getId(), is(equalTo(template.getOwner().getId())));
+        assertThat(jpaTemplate.isDisableRendering(), is(equalTo(template.isDisableRendering())));
+        assertThat(jpaTemplate.getRatings(), is(equalTo(template.getRatings())));
+        assertThat(jpaTemplate.getTags(), is(equalTo(template.getTags())));
+        assertThat(jpaTemplate.getCategories(), is(equalTo(template.getCategories())));
+        assertThat(jpaTemplate.isFeatured(), is(equalTo(template.isFeatured())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetRatingConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetRatingConverterTest.java
new file mode 100644
index 0000000..e4cd295
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetRatingConverterTest.java
@@ -0,0 +1,57 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.JpaWidgetRating;
+import org.apache.rave.portal.model.WidgetRating;
+import org.apache.rave.portal.model.impl.WidgetRatingImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml", "classpath:test-dataContext.xml"})
+public class JpaWidgetRatingConverterTest {
+
+    @Autowired
+    JpaWidgetRatingConverter converter;
+
+    @Before
+    public void setup() {
+
+    }
+
+    @Test
+    public void testNoConversion() {
+        JpaWidgetRating template = new JpaWidgetRating();
+        assertThat(converter.convert(template), is(sameInstance(template)));
+    }
+
+    @Test
+    public void nullConversion() {
+        WidgetRating template = null;
+        assertThat(converter.convert(template), is(nullValue()));
+    }
+
+
+    @Test
+    public void convertValid() {
+        WidgetRating template = new WidgetRatingImpl();
+        template.setScore(1);
+        template.setUserId(42L);
+        template.setWidgetId(24L);
+        
+        JpaWidgetRating jpaTemplate = converter.convert(template);
+
+        assertThat(jpaTemplate, is(not(sameInstance(template))));
+        assertThat(jpaTemplate, is(instanceOf(JpaWidgetRating.class)));
+        assertThat(jpaTemplate.getScore(), is(equalTo(template.getScore())));
+        assertThat(jpaTemplate.getUserId(), is(equalTo(template.getUserId())));
+        assertThat(jpaTemplate.getWidgetId(), is(equalTo(template.getWidgetId())));
+    }
+
+}
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetTagConverterTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetTagConverterTest.java
new file mode 100644
index 0000000..efe9836
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/model/conversion/JpaWidgetTagConverterTest.java
@@ -0,0 +1,50 @@
+package org.apache.rave.portal.model.conversion;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.WidgetTagImpl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.Date;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})
+public class JpaWidgetTagConverterTest {
+  
+    @Autowired 
+    JpaWidgetTagConverter jpaWidgetTagConverter;
+    
+    @Test
+    public void convert_valid_widgetTaq(){
+        WidgetTag widgetTag = new WidgetTagImpl();
+        widgetTag.setCreatedDate(new Date());
+        widgetTag.setUser(new JpaUser());
+        widgetTag.setWidgetId(3L);
+        widgetTag.setTag(new JpaTag(1L, "news"));
+        JpaWidgetTag jpaWidgetTag = jpaWidgetTagConverter.convert(widgetTag);
+        assertNotNull(jpaWidgetTag);
+        assertEquals(widgetTag.getCreatedDate(), jpaWidgetTag.getCreatedDate());
+        assertSame(widgetTag.getTag(), jpaWidgetTag.getTag());
+        assertSame(widgetTag.getUser(), jpaWidgetTag.getUser());
+        assertEquals(widgetTag.getWidgetId(), jpaWidgetTag.getWidgetId());
+    }
+
+    @Test
+    public void convert_valid_jpaWidgetTaq(){
+        JpaWidgetTag widgetTag = new JpaWidgetTag();
+        widgetTag.setCreatedDate(new Date());
+        widgetTag.setUser(new JpaUser());
+        widgetTag.setWidgetId(3L);
+        widgetTag.setTag(new JpaTag(1L, "news"));
+        JpaWidgetTag jpaWidgetTag = jpaWidgetTagConverter.convert(widgetTag);
+        assertNotNull(jpaWidgetTag);
+        assertSame(widgetTag, jpaWidgetTag);
+    }
+}
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java
similarity index 100%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/repository/JpaApplicationDataRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaApplicationDataRepositoryTest.java
similarity index 80%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/repository/JpaApplicationDataRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaApplicationDataRepositoryTest.java
index 92e2186..02012df 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/repository/JpaApplicationDataRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaApplicationDataRepositoryTest.java
@@ -16,9 +16,11 @@
  * specific language governing permissions and limitations

  * under the License.

  */

-package org.apache.rave.opensocial.repository;

+package org.apache.rave.portal.repository.impl;

 

-import org.apache.rave.opensocial.model.ApplicationData;

+import org.apache.rave.portal.model.ApplicationData;

+import org.apache.rave.portal.model.JpaApplicationData;

+import org.apache.rave.portal.repository.ApplicationDataRepository;

 import org.junit.Before;

 import org.junit.Test;

 import org.junit.runner.RunWith;

@@ -40,8 +42,8 @@
 import static org.junit.Assert.assertThat;

 

 @RunWith(SpringJUnit4ClassRunner.class)

-@ContextConfiguration(locations = {"classpath:rave-shindig-test-applicationContext.xml",

-        "classpath:rave-shindig-test-dataContext.xml"})

+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml",

+        "classpath:test-dataContext.xml"})

 public class JpaApplicationDataRepositoryTest {

     @PersistenceContext

     private EntityManager manager;

@@ -66,7 +68,7 @@
 

     @Test

     public void get_valid() {

-        ApplicationData applicationData = repository.get(VALID_APPLICATION_DATA_ID);

+        JpaApplicationData applicationData = (JpaApplicationData) repository.get(VALID_APPLICATION_DATA_ID);

         validateApplicationData(applicationData);

     }

 

@@ -78,7 +80,7 @@
 

     @Test

     public void getApplicationData_byUserIdAndApplicationId_valid() {

-        ApplicationData applicationData = repository.getApplicationData(VALID_USER_ID, VALID_APPLICATION_ID);

+        JpaApplicationData applicationData = (JpaApplicationData) repository.getApplicationData(VALID_USER_ID, VALID_APPLICATION_ID);

         validateApplicationData(applicationData);

     }

 

@@ -92,7 +94,7 @@
     public void getApplicationData_byUserIdsAndApplicationId_valid() {

         List<ApplicationData> applicationData = repository.getApplicationData(Arrays.asList(VALID_USER_ID),

                 VALID_APPLICATION_ID);

-        validateApplicationData(applicationData.get(0));

+        validateApplicationData((JpaApplicationData)applicationData.get(0));

     }

 

     @Test

@@ -109,17 +111,17 @@
                 VALID_APPLICATION_ID);

         //Since there is no appdata in the database for "NO-DATA-USER" we should only get back one result

         assertThat(applicationData.size(), is(equalTo(1)));

-        validateApplicationData(applicationData.get(0));

+        validateApplicationData((JpaApplicationData)applicationData.get(0));

     }

 

     @Test

     @Transactional

     @Rollback(true)

     public void save_newEntity() {

-        ApplicationData applicationData = new ApplicationData(null, VALID_USER_ID, SECOND_VALID_APPLICATION_ID,

+        ApplicationData applicationData = new JpaApplicationData(null, VALID_USER_ID, SECOND_VALID_APPLICATION_ID,

                 validApplicationDataMap);

 

-        ApplicationData saved = repository.save(applicationData);

+        JpaApplicationData saved = (JpaApplicationData)repository.save(applicationData);

         manager.flush();

         assertThat(saved.getEntityId(), is(notNullValue()));

     }

@@ -128,16 +130,16 @@
     @Transactional

     @Rollback(true)

     public void save_existingEntity() {

-        ApplicationData applicationData = new ApplicationData(VALID_APPLICATION_DATA_ID, VALID_USER_ID,

+        JpaApplicationData applicationData = new JpaApplicationData(VALID_APPLICATION_DATA_ID, VALID_USER_ID,

                 VALID_APPLICATION_ID, new HashMap<String, String>());

 

-        ApplicationData saved = repository.save(applicationData);

+        JpaApplicationData saved = (JpaApplicationData)repository.save(applicationData);

         manager.flush();

         assertThat(saved, is(not(sameInstance(applicationData))));

         assertThat(saved.getEntityId(), is(equalTo(applicationData.getEntityId())));

     }

 

-    private void validateApplicationData(ApplicationData applicationData) {

+    private void validateApplicationData(JpaApplicationData applicationData) {

         assertThat(applicationData, is(not(nullValue())));

         assertThat(applicationData.getEntityId(), is(equalTo(VALID_APPLICATION_DATA_ID)));

         assertThat(applicationData.getUserId(), is(equalTo(VALID_USER_ID)));

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepositoryTest.java
similarity index 93%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepositoryTest.java
index 9c69827..04e713e 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaAuthorityRepositoryTest.java
@@ -20,7 +20,11 @@
 package org.apache.rave.portal.repository.impl;
 
 import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.JpaAuthority;
+import org.apache.rave.portal.model.JpaUser;
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.repository.AuthorityRepository;
+import org.apache.rave.portal.repository.UserRepository;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -33,10 +37,8 @@
 import javax.persistence.PersistenceContext;
 import java.util.List;
 
-import org.apache.rave.portal.repository.AuthorityRepository;
-import org.apache.rave.portal.repository.UserRepository;
+import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
 
 /**
  *
@@ -59,7 +61,7 @@
 
     @Test
     public void getById_validId() {
-        final Authority authority = repository.get(VALID_ID);
+        final JpaAuthority authority = (JpaAuthority)repository.get(VALID_ID);
         assertNotNull(authority);
         assertEquals(VALID_ID, authority.getEntityId());
     }
@@ -81,7 +83,7 @@
         assertEquals(authorityName, authority.getAuthority());
         assertTrue(authority.getUsers().isEmpty());
 
-        User newUser = new User();
+        User newUser = new JpaUser();
         newUser.setUsername("adminuser");
         newUser.addAuthority(authority);
         newUser = userRepository.save(newUser);
@@ -94,11 +96,11 @@
     @Test
     public void addOrDeleteAuthorityDoesNotAffectUser() {
         final String authorityName = "guest";
-        Authority authority = new Authority();
+        Authority authority = new JpaAuthority();
         authority.setAuthority(authorityName);
         User user = userRepository.get(1L);
 
-        Assert.assertNotNull("User is not null", user);
+        Assert.assertNotNull("User is null", user);
         Assert.assertTrue("User has no authorities", user.getAuthorities().isEmpty());
         assertNull("No authority guest", repository.getByAuthority(authorityName));
 
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaCategoryRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaCategoryRepositoryTest.java
new file mode 100644
index 0000000..4afce3e
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaCategoryRepositoryTest.java
@@ -0,0 +1,168 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.repository.impl;

+

+import org.apache.openjpa.persistence.PersistenceException;

+import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.repository.CategoryRepository;

+import org.junit.Before;

+import org.junit.Ignore;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.annotation.Rollback;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+import org.springframework.transaction.annotation.Transactional;

+

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

+import java.util.Date;

+import java.util.List;

+

+import static org.junit.Assert.*;

+import static org.hamcrest.CoreMatchers.*;

+

+@Transactional

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+

+public class JpaCategoryRepositoryTest {

+

+    private final Long VALID_ENTITY_ID = 1L;

+    private final Long INVALID_ENTITY_ID = -12345L;

+    private final Long VALID_USER_ID = 1L;

+    private final Long VALID_WIDGET_ID = 1L;

+

+    private User validUser;

+    private JpaWidget validWidget;

+

+    @PersistenceContext

+    private EntityManager manager;

+

+    @Autowired

+    private CategoryRepository repository;

+

+    private static final String DUPLICATE_TEXT_VALUE = "Sample Category";

+

+    @Before

+    public void setup() {

+        validUser = new JpaUser(VALID_USER_ID);

+        validWidget = new JpaWidget();

+        validWidget.setEntityId(VALID_WIDGET_ID);

+    }

+

+    @Test

+    public void getById_validId() {

+        JpaCategory category = (JpaCategory) repository.get(VALID_ENTITY_ID);

+        assertThat(category.getEntityId(), is(equalTo(VALID_ENTITY_ID)));

+    }

+

+    @Test

+    public void getById_invalidId() {

+        assertThat(repository.get(INVALID_ENTITY_ID), is(nullValue()));

+    }

+

+    @Test

+    @Rollback(true)

+    public void save_newEntity() throws Exception {

+        final String NEW_TEXT = "My New Category";

+        Date now = new Date();

+        JpaCategory category = new JpaCategory();

+        category.setLastModifiedDate(now);

+        category.setLastModifiedUser(validUser);

+        category.setText(NEW_TEXT);

+        category.setCreatedDate(now);

+        category.setCreatedUser(validUser);

+

+        assertThat(category.getEntityId(), is(nullValue()));

+        repository.save(category);

+

+        Long newEntityId = category.getEntityId();

+        assertThat(newEntityId, is(notNullValue()));

+        // verify that it persisted ok

+        assertThat((JpaCategory)repository.get(newEntityId), is(category));

+    }

+

+    @Test

+    @Rollback(true)

+    public void save_existingEntity() {

+        final String UPDATED_TEXT = "changed the text";

+        Category category = repository.get(VALID_ENTITY_ID);

+        assertThat(category.getText(), is(not(UPDATED_TEXT)));

+        category.setText(UPDATED_TEXT);

+        repository.save(category);

+        // fetch again and verify update

+        Category modCategory = repository.get(VALID_ENTITY_ID);

+        assertThat(modCategory.getText(), is(UPDATED_TEXT));

+    }

+

+    @Test

+    @Rollback(true)

+    public void delete() {

+        Category entity = repository.get(VALID_ENTITY_ID);

+        assertThat(entity, is(notNullValue()));

+        repository.delete(entity);

+        assertThat(repository.get(VALID_ENTITY_ID), is(nullValue()));

+    }

+

+    @Test

+    public void getAll() {

+        List<Category> list = repository.getAll();

+        assertThat(list.size(), is(4));

+        // verify proper sorting alphabetical by text attribute

+        String lastText = "";

+        for (Category wc : list) {

+            String currentText = wc.getText();

+            assertThat(currentText.compareTo(lastText) > 0, is(true));

+            lastText = currentText;

+        }

+    }

+

+    /**

+     * Verify that a unique constraint exception is thrown if a duplicate text value is attempted to be added

+     */

+    @Test

+    @Ignore //This should just merge in rather than throw an exception, which it looks like it does correctly

+    public void save_duplicateText_exception() {

+        Date now = new Date();

+        User user = new JpaUser(1L);

+

+        JpaCategory wc = new JpaCategory();

+        wc.setText(DUPLICATE_TEXT_VALUE);

+        wc.setCreatedDate(now);

+        wc.setCreatedUser(user);

+        wc.setLastModifiedDate(now);

+        wc.setLastModifiedUser(user);

+

+        boolean gotExpectedException = false;

+        try {

+            repository.save(wc);

+            manager.flush();

+        } catch (PersistenceException e) {

+            assertThat(e.getCause().toString().contains("Unique"), is(true));

+            gotExpectedException = true;

+        } finally {

+            if (!gotExpectedException) {

+                fail("Expected to get a PersistenceException due to Unique Constraint Violation");

+            }

+        }

+    }

+}

diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaOAuthConsumerStoreRepositoryTest.java
similarity index 78%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaOAuthConsumerStoreRepositoryTest.java
index 690d68c..47915d2 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaOAuthConsumerStoreRepositoryTest.java
@@ -17,12 +17,11 @@
  * under the License.
  */
 
-package org.apache.rave.gadgets.oauth.repository;
+package org.apache.rave.portal.repository.impl;
 
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.portal.model.JpaOAuthConsumerStore;
+import org.apache.rave.portal.model.OAuthConsumerStore;
+import org.apache.rave.portal.repository.OAuthConsumerStoreRepository;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,17 +29,18 @@
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.transaction.annotation.Transactional;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import static junit.framework.Assert.*;
 
 /**
- * Test for {@link org.apache.rave.gadgets.oauth.repository.impl.JpaOAuthConsumerStoreRepository}
+ * Test for {@link org.apache.rave.portal.repository.impl.JpaOAuthConsumerStoreRepository}
  */
 @Transactional
 @RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"classpath:rave-shindig-test-applicationContext.xml",
-        "classpath:rave-shindig-test-dataContext.xml"})
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml",
+        "classpath:test-dataContext.xml"})
 public class JpaOAuthConsumerStoreRepositoryTest {
     private static final String GADGET_URI = "http://localhost:8080/samplecontainer/examples/oauth.xml";
     private static final String SERVICE_NAME_GOOGLE = "Google";
@@ -58,7 +58,7 @@
         final OAuthConsumerStore store = repository.findByUriAndServiceName(GADGET_URI, SERVICE_NAME_GOOGLE);
         assertNotNull("OAuthConsumerStore In test db", store);
         assertEquals("gadgetSecret", store.getConsumerSecret());
-        assertEquals(OAuthConsumerStore.KeyType.HMAC_SYMMETRIC, store.getKeyType());
+        assertEquals(JpaOAuthConsumerStore.KeyType.HMAC_SYMMETRIC, store.getKeyType());
     }
 
     @Test
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaOAuthTokenInfoRepositoryTest.java
similarity index 63%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaOAuthTokenInfoRepositoryTest.java
index 82fcff2..484d9a2 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaOAuthTokenInfoRepositoryTest.java
@@ -17,10 +17,11 @@
  * under the License.
  */
 
-package org.apache.rave.gadgets.oauth.repository;
+package org.apache.rave.portal.repository.impl;
 
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
-import org.apache.rave.gadgets.oauth.service.OAuthTokenInfoService;
+import org.apache.rave.portal.model.JpaOAuthTokenInfo;
+import org.apache.rave.portal.model.OAuthTokenInfo;
+import org.apache.rave.portal.repository.OAuthTokenInfoRepository;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -32,17 +33,15 @@
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.*;
 
 /**
- * Test class for {@link org.apache.rave.gadgets.oauth.repository.impl.JpaOAuthTokenInfoRepository}
+ * Test class for {@link org.apache.rave.portal.repository.impl.JpaOAuthTokenInfoRepository}
  */
 @Transactional
 @RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"classpath:rave-shindig-test-applicationContext.xml",
-        "classpath:rave-shindig-test-dataContext.xml"})
+@ContextConfiguration(locations = {"classpath:test-applicationContext.xml",
+        "classpath:test-dataContext.xml"})
 public class JpaOAuthTokenInfoRepositoryTest {
 
     private static final String INVALID_USER = "Invalid user";
@@ -57,13 +56,10 @@
     @Autowired
     OAuthTokenInfoRepository repository;
 
-    @Autowired
-    OAuthTokenInfoService service;
-
     @Test
     public void testFindOAuthTokenInfo() throws Exception {
         OAuthTokenInfo tokenInfo = repository.findOAuthTokenInfo(VALID_USER,
-                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
+                APP_URL, JpaOAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
         assertNotNull(tokenInfo);
         assertEquals("accessToken", tokenInfo.getAccessToken());
     }
@@ -71,7 +67,7 @@
     @Test
     public void testFindOAuthTokenInfo_nullValue() throws Exception {
         OAuthTokenInfo tokenInfo = repository.findOAuthTokenInfo(INVALID_USER,
-                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
+                APP_URL, JpaOAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
         assertNull(tokenInfo);
     }
 
@@ -79,23 +75,11 @@
     @Rollback
     public void testDeleteOAuthTokenInfo() throws Exception {
         OAuthTokenInfo tokenInfo = repository.findOAuthTokenInfo(VALID_USER,
-                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
+                APP_URL, JpaOAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
         assertNotNull(tokenInfo);
         repository.delete(tokenInfo);
         tokenInfo = repository.findOAuthTokenInfo(VALID_USER,
-                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
-        assertNull(tokenInfo);
-    }
-
-    @Test
-    @Rollback
-    public void testDeleteOAuthTokenInfo_ThroughService() throws Exception {
-        OAuthTokenInfo tokenInfo = repository.findOAuthTokenInfo(VALID_USER,
-                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
-        assertNotNull(tokenInfo);
-        service.deleteOAuthTokenInfo(VALID_USER, APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
-        tokenInfo = repository.findOAuthTokenInfo(VALID_USER,
-                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
+                APP_URL, JpaOAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
         assertNull(tokenInfo);
     }
 
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepositoryTest.java
similarity index 92%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepositoryTest.java
index da7254d..077e4ca 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageLayoutRepositoryTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.rave.portal.repository.impl;
 
+import org.apache.rave.portal.model.JpaPageLayout;
 import org.apache.rave.portal.model.PageLayout;
 import org.apache.rave.portal.repository.PageLayoutRepository;
 import org.junit.Test;
@@ -78,7 +79,7 @@
     
     @Test
     public void getByPageLayoutCode() {
-        PageLayout pageLayout = repository.getByPageLayoutCode(VALID_LAYOUT_CODE);
+        JpaPageLayout pageLayout = (JpaPageLayout)repository.getByPageLayoutCode(VALID_LAYOUT_CODE);
         assertThat(pageLayout.getCode(), is(VALID_LAYOUT_CODE));
         assertThat(pageLayout.getNumberOfRegions(), is(2L));
         assertThat(pageLayout.getEntityId(), is(notNullValue(Long.class)));
@@ -86,6 +87,6 @@
 
     @Test
     public void getByPageLayoutCode_invalidCode() {
-        assertThat(repository.getByPageLayoutCode(INVALID_LAYOUT_CODE), is(nullValue(PageLayout.class))); 
+        assertThat((JpaPageLayout)repository.getByPageLayoutCode(INVALID_LAYOUT_CODE), is(nullValue(JpaPageLayout.class)));
     }    
 }
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
similarity index 90%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
index 9a2aa07..d73614f 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageRepositoryTest.java
@@ -18,11 +18,7 @@
  */
 package org.apache.rave.portal.repository.impl;
 
-import org.apache.rave.portal.model.Page;
-import org.apache.rave.portal.model.PageTemplate;
-import org.apache.rave.portal.model.PageType;
-import org.apache.rave.portal.model.PageUser;
-import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.*;
 import org.apache.rave.portal.repository.PageRepository;
 import org.apache.rave.portal.repository.PageTemplateRepository;
 import org.apache.rave.portal.repository.UserRepository;
@@ -70,12 +66,12 @@
     @Autowired
     private PageTemplateRepository pageTemplateRepository;
 
-    private User user;
+    private JpaUser user;
     private PageTemplate defaultPageTemplate;
-    
+
     @Before
     public void setup(){
-        user = userRepository.get(CREATED_USER_ID);
+        user = (JpaUser)userRepository.get(CREATED_USER_ID);
         defaultPageTemplate = pageTemplateRepository.getDefaultPage(PageType.PERSON_PROFILE);
     }
 
@@ -87,7 +83,7 @@
         assertThat(pages.get(0).getRegions().size(), equalTo(2));
         assertThat(pages.get(0).getRegions().get(0).getRegionWidgets().size(), equalTo(2));
         assertThat(pages.get(0).getRegions().get(0).getRegionWidgets().get(0).getWidget().getUrl(), equalTo(WIDGET_URL));
-        
+
         List<PageUser> pageUserPages = repository.getPagesForUser(USER_ID, PageType.USER);
         // test that the query returns the pages in proper render sequence order
         Long lastRenderSequence = -1L;
@@ -121,7 +117,7 @@
         assertThat(pages, is(notNullValue()));
         assertThat(pages.size(), is(2));
         assertThat(pages.get(0).getRegions().size(), is(1));
-        assertThat(pages.get(0).getParentPage().getEntityId(), is(3L));
+        assertThat(pages.get(0).getParentPage().getId(), is(3L));
 
         List<PageUser> pageUserPages = repository.getPagesForUser(USER_ID, PageType.SUB_PAGE);
         // test that the query returns the pages in proper render sequence order
@@ -155,7 +151,7 @@
     public void getById_valid_userPage() {
         Page p = repository.get(USER_PAGE_ID);
         assertThat(p, is(notNullValue()));
-        assertThat(p.getEntityId(), is(equalTo(USER_PAGE_ID)));
+        assertThat(p.getId(), is(equalTo(USER_PAGE_ID)));
         assertThat(p.getPageType(), is(PageType.USER));
         assertThat(p.getParentPage(), is(nullValue(Page.class)));
         assertThat(p.getSubPages().isEmpty(), is(true));
@@ -164,7 +160,7 @@
     @Test
     public void getById_valid_personProfilePage() {
         Page p = repository.get(PERSON_PROFILE_PAGE_ID);
-        assertThat(p.getEntityId(), is(equalTo(PERSON_PROFILE_PAGE_ID)));
+        assertThat(p.getId(), is(equalTo(PERSON_PROFILE_PAGE_ID)));
         assertThat(p.getPageType(), is(PageType.PERSON_PROFILE));
         assertThat(p.getParentPage(), is(nullValue(Page.class)));
         assertThat(p.getSubPages().isEmpty(), is(false));
@@ -173,19 +169,19 @@
         Long lastRenderSequence = -1L;
         PageUser pageUser;
         for (Page subPage : p.getSubPages()) {
-            pageUser = repository.getSingleRecord(p.getOwner().getEntityId(), subPage.getEntityId());
+            pageUser = repository.getSingleRecord(p.getOwner().getId(), subPage.getId());
             Long currentRenderSequence =  pageUser.getRenderSequence();
             assertThat(currentRenderSequence > lastRenderSequence, is(true));
             lastRenderSequence = currentRenderSequence;
         }
-        
+
     }
 
     @Test
     public void getById_valid_subPagePage() {
         Page p = repository.get(SUB_PAGE_ID);
         assertThat(p, is(notNullValue()));
-        assertThat(p.getEntityId(), is(equalTo(SUB_PAGE_ID)));
+        assertThat(p.getId(), is(equalTo(SUB_PAGE_ID)));
         assertThat(p.getPageType(), is(PageType.SUB_PAGE));
         assertThat(p.getParentPage(), is(notNullValue(Page.class)));
         assertThat(p.getSubPages().isEmpty(), is(true));
@@ -208,7 +204,7 @@
         // ensure pages are deleted
         assertThat(repository.getAllPages(USER_ID, PageType.USER).isEmpty(), is(true));
     }
-    
+
     @Test
     @Transactional(readOnly = false)
     @Rollback(true)
@@ -228,12 +224,12 @@
         assertEquals("Widgets on sub page 2", 1, subPage2.getRegions().get(0).getRegionWidgets().size());
         assertEquals("Regions on sub page 1", 1, subPage1.getRegions().size());
         assertEquals("Regions on sub page 2", 1, subPage2.getRegions().size());
-        assertNull("no sub pages of sub page 1", subPage1.getSubPages());
-        assertNull("no sub pages of sub page 2", subPage2.getSubPages());
-        assertEquals("sub page 1 refers to parent page", page.getEntityId(), subPage1.getParentPage().getEntityId());
-        assertEquals("sub page 2 refers to parent page", page.getEntityId(), subPage2.getParentPage().getEntityId());
-        assertEquals("sub page 1 regions refers to sub page 1", subPage1.getEntityId(), subPage1.getRegions().get(0).getPage().getEntityId());
-        assertEquals("sub page 2 regions refers to sub page 2", subPage2.getEntityId(), subPage2.getRegions().get(0).getPage().getEntityId());
+        assertThat(subPage1.getSubPages().isEmpty(), is(true));
+        assertThat(subPage2.getSubPages().isEmpty(), is(true));
+        assertEquals("sub page 1 refers to parent page", page.getId(), subPage1.getParentPage().getId());
+        assertEquals("sub page 2 refers to parent page", page.getId(), subPage2.getParentPage().getId());
+        assertEquals("sub page 1 regions refers to sub page 1", subPage1.getId(), subPage1.getRegions().get(0).getPage().getId());
+        assertEquals("sub page 2 regions refers to sub page 2", subPage2.getId(), subPage2.getRegions().get(0).getPage().getId());
         assertEquals("sub page 1 has one column layout", "columns_1", subPage1.getPageLayout().getCode());
         assertEquals("sub page 2 has one column layout", "columns_1", subPage2.getPageLayout().getCode());
         assertEquals(PageType.SUB_PAGE, subPage1.getPageType());
@@ -243,7 +239,7 @@
         assertSame(user, subPage1.getOwner());
         assertSame(user, subPage2.getOwner());
     }
-    
+
     @Test
     public void hasPersonPage_true(){
         assertTrue(repository.hasPersonPage(USER_ID));
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepositoryTest.java
similarity index 83%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepositoryTest.java
index 59eb83d..4170d34 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPageTemplateRepositoryTest.java
@@ -18,10 +18,7 @@
  */

 package org.apache.rave.portal.repository.impl;

 

-import org.apache.rave.portal.model.PageTemplate;

-import org.apache.rave.portal.model.PageTemplateRegion;

-import org.apache.rave.portal.model.PageTemplateWidget;

-import org.apache.rave.portal.model.PageType;

+import org.apache.rave.portal.model.*;

 import org.apache.rave.portal.repository.PageTemplateRepository;

 import org.junit.Test;

 import org.junit.runner.RunWith;

@@ -66,7 +63,7 @@
     @Test

     public void getDefaultPersonPage_valid(){

         // get default page template

-        PageTemplate pt = pageTemplateRepository.getDefaultPage(PageType.PERSON_PROFILE);

+        JpaPageTemplate pt = (JpaPageTemplate)pageTemplateRepository.getDefaultPage(PageType.PERSON_PROFILE);

         // default page tests

         assertNotNull(pt);

         assertEquals("Template for person profile pages", pt.getDescription());

@@ -79,8 +76,8 @@
         assertEquals("# of widgets on parent page region", 2, pt.getPageTemplateRegions().get(0).getPageTemplateWidgets().size());

         assertEquals("# of sub pages for parent page",2, pt.getSubPageTemplates().size());

         // get default page sub pages

-        PageTemplate subPage1 = pt.getSubPageTemplates().get(0);

-        PageTemplate subPage2 = pt.getSubPageTemplates().get(1);

+        JpaPageTemplate subPage1 = (JpaPageTemplate)pt.getSubPageTemplates().get(0);

+        JpaPageTemplate subPage2 = (JpaPageTemplate)pt.getSubPageTemplates().get(1);

         // sub page 1 tests

         assertNotNull(subPage1);

         assertEquals("Template for the About sub page for the person profile", subPage1.getDescription());

@@ -104,50 +101,50 @@
         assertEquals("# of widgets on sub page 2 region 1", 1, subPage2.getPageTemplateRegions().get(0).getPageTemplateWidgets().size());

         assertEquals("# of sub pages for sub page 2", 0, subPage2.getSubPageTemplates().size());

         // parent page region tests

-        PageTemplateRegion ptRegion1 = pt.getPageTemplateRegions().get(0);

+        JpaPageTemplateRegion ptRegion1 = (JpaPageTemplateRegion)pt.getPageTemplateRegions().get(0);

         assertEquals(pt.getEntityId(), ptRegion1.getPageTemplate().getEntityId());

         assertEquals(0, ptRegion1.getRenderSequence());

         assertEquals(2, ptRegion1.getPageTemplateWidgets().size());

         assertTrue(ptRegion1.isLocked());

         // parent page region 1 widget 1 tests

         PageTemplateWidget ptw1 = ptRegion1.getPageTemplateWidgets().get(0);

-        assertEquals(ptw1.getPageTemplateRegion().getEntityId(), ptRegion1.getEntityId());

+        assertEquals(((JpaPageTemplateRegion)ptw1.getPageTemplateRegion()).getEntityId(), ptRegion1.getEntityId());

         assertEquals(0, ptw1.getRenderSeq());

         assertNotNull(ptw1.getWidget());

         assertTrue(ptw1.isLocked());

         // parent page region widget 2 tests

         PageTemplateWidget ptw2 = ptRegion1.getPageTemplateWidgets().get(1);

-        assertEquals(ptw2.getPageTemplateRegion().getEntityId(), ptRegion1.getEntityId());

+        assertEquals(((JpaPageTemplateRegion)ptw2.getPageTemplateRegion()).getEntityId(), ptRegion1.getEntityId());

         assertEquals(1, ptw2.getRenderSeq());

         assertNotNull(ptw2.getWidget());

         assertTrue(ptw2.isLocked());

         // sub page 1 region 1 tests

-        PageTemplateRegion sp1Region1 = subPage1.getPageTemplateRegions().get(0);

+        JpaPageTemplateRegion sp1Region1 = (JpaPageTemplateRegion)subPage1.getPageTemplateRegions().get(0);

         assertEquals(subPage1.getEntityId(), sp1Region1.getPageTemplate().getEntityId());

         assertEquals(0, sp1Region1.getRenderSequence());

         assertEquals(2, sp1Region1.getPageTemplateWidgets().size());

         assertTrue(sp1Region1.isLocked());

         // sub page 1 region 1 widget 1 tests

         PageTemplateWidget spw1 = sp1Region1.getPageTemplateWidgets().get(0);

-        assertEquals(spw1.getPageTemplateRegion().getEntityId(), sp1Region1.getEntityId());

+        assertEquals(((JpaPageTemplateRegion)spw1.getPageTemplateRegion()).getEntityId(), sp1Region1.getEntityId());

         assertEquals(0, spw1.getRenderSeq());

         assertNotNull(spw1.getWidget());

         assertTrue(spw1.isLocked());

         // sub page 1 region 1 widget 2 tests

         PageTemplateWidget spw2 = sp1Region1.getPageTemplateWidgets().get(1);

-        assertEquals(spw2.getPageTemplateRegion().getEntityId(), sp1Region1.getEntityId());

+        assertEquals(((JpaPageTemplateRegion)spw2.getPageTemplateRegion()).getEntityId(), sp1Region1.getEntityId());

         assertEquals(1, spw2.getRenderSeq());

         assertNotNull(spw2.getWidget());

         assertTrue(spw2.isLocked());

         // sub page 2 region tests

-        PageTemplateRegion sp2Region1 = subPage2.getPageTemplateRegions().get(0);

+        JpaPageTemplateRegion sp2Region1 = (JpaPageTemplateRegion)subPage2.getPageTemplateRegions().get(0);

         assertEquals(subPage2.getEntityId(), sp2Region1.getPageTemplate().getEntityId());

         assertEquals(0, sp2Region1.getRenderSequence());

         assertEquals(1, sp2Region1.getPageTemplateWidgets().size());

         assertTrue(sp2Region1.isLocked());

         // sub page 2 region widget 1 tests

         PageTemplateWidget sp2w1 = sp2Region1.getPageTemplateWidgets().get(0);

-        assertEquals(sp2w1.getPageTemplateRegion().getEntityId(), sp2Region1.getEntityId());

+        assertEquals(((JpaPageTemplateRegion)sp2w1.getPageTemplateRegion()).getEntityId(), sp2Region1.getEntityId());

         assertEquals(0, sp2w1.getRenderSeq());

         assertNotNull(sp2w1.getWidget());

         assertTrue(sp2w1.isLocked());

@@ -158,7 +155,7 @@
     @Test

     public void getDefaultUserPage_valid(){

         // get default page template

-        PageTemplate pt = pageTemplateRepository.getDefaultPage(PageType.USER);

+        JpaPageTemplate pt = (JpaPageTemplate)pageTemplateRepository.getDefaultPage(PageType.USER);

         // default page tests

         assertNotNull(pt);

         assertEquals("User profile pages", pt.getDescription());

@@ -171,20 +168,20 @@
         assertEquals("# of widgets on parent page region", 2, pt.getPageTemplateRegions().get(0).getPageTemplateWidgets().size());

 

         // parent page region tests

-        PageTemplateRegion ptRegion1 = pt.getPageTemplateRegions().get(0);

+        JpaPageTemplateRegion ptRegion1 = (JpaPageTemplateRegion)pt.getPageTemplateRegions().get(0);

         assertEquals(pt.getEntityId(), ptRegion1.getPageTemplate().getEntityId());

         assertEquals(0, ptRegion1.getRenderSequence());

         assertEquals(2, ptRegion1.getPageTemplateWidgets().size());

         assertTrue(ptRegion1.isLocked());

         // parent page region 1 widget 1 tests

         PageTemplateWidget ptw1 = ptRegion1.getPageTemplateWidgets().get(0);

-        assertEquals(ptw1.getPageTemplateRegion().getEntityId(), ptRegion1.getEntityId());

+        assertEquals(((JpaPageTemplateRegion)ptw1.getPageTemplateRegion()).getEntityId(), ptRegion1.getEntityId());

         assertEquals(0, ptw1.getRenderSeq());

         assertNotNull(ptw1.getWidget());

         assertTrue(ptw1.isLocked());

         // parent page region widget 2 tests

         PageTemplateWidget ptw2 = ptRegion1.getPageTemplateWidgets().get(1);

-        assertEquals(ptw2.getPageTemplateRegion().getEntityId(), ptRegion1.getEntityId());

+        assertEquals(((JpaPageTemplateRegion)ptw2.getPageTemplateRegion()).getEntityId(), ptRegion1.getEntityId());

         assertEquals(1, ptw2.getRenderSeq());

         assertNotNull(ptw2.getWidget());

         assertTrue(ptw2.isLocked());

diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/repository/JpaPersonRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPersonRepositoryTest.java
similarity index 90%
rename from rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/repository/JpaPersonRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPersonRepositoryTest.java
index 634c05b..5f27025 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/repository/JpaPersonRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPersonRepositoryTest.java
@@ -17,29 +17,26 @@
  * under the License.
  */
 
-package org.apache.rave.opensocial.repository;
-
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
+package org.apache.rave.portal.repository.impl;
 
 import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.repository.PersonRepository;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
 
 @RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations={"classpath:rave-shindig-test-applicationContext.xml",
-        "classpath:rave-shindig-test-dataContext.xml"})
+@ContextConfiguration(locations={"classpath:test-applicationContext.xml",
+        "classpath:test-dataContext.xml"})
 public class JpaPersonRepositoryTest {
 
     private static final String VALID_USER = "canonical";
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepositoryTest.java
similarity index 100%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaPortalPreferenceRepositoryTest.java
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionRepositoryTest.java
similarity index 77%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionRepositoryTest.java
index 92899a2..6d8f3c0 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionRepositoryTest.java
@@ -19,8 +19,11 @@
 
 package org.apache.rave.portal.repository.impl;
 
+import org.apache.rave.portal.model.JpaRegion;
+import org.apache.rave.portal.model.JpaRegionWidget;
 import org.apache.rave.portal.model.Region;
 import org.apache.rave.portal.model.RegionWidget;
+import org.apache.rave.portal.repository.RegionRepository;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,13 +36,7 @@
 import javax.persistence.PersistenceContext;
 import java.util.ArrayList;
 
-import org.apache.rave.portal.repository.RegionRepository;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
 
 @Transactional
@@ -58,7 +55,7 @@
 
     @Test
     public void getById_validId() {
-        Region region = repository.get(REGION_ID);
+        JpaRegion region = (JpaRegion)repository.get(REGION_ID);
         assertThat(region, is(notNullValue()));
         assertThat(region.getEntityId(), is(equalTo(1L)));
         assertThat(region.getRegionWidgets().size(), is(equalTo(2)));
@@ -66,16 +63,16 @@
 
     @Test
     public void getById_invalidId() {
-        Region region = repository.get(INVALID_REGION_ID);
+        JpaRegion region = (JpaRegion)repository.get(INVALID_REGION_ID);
         assertThat(region, is(nullValue()));
     }
 
     @Test
     @Rollback(true)
     public void save_newEntity() {
-        Region region = new Region();
+        JpaRegion region = new JpaRegion();
         region.setRegionWidgets(new ArrayList<RegionWidget>());
-        Region saved = repository.save(region);
+        JpaRegion saved = (JpaRegion)repository.save(region);
         manager.flush();
         assertThat(saved, is(sameInstance(region)));
         assertThat(saved.getEntityId(), is(notNullValue()));
@@ -84,10 +81,10 @@
     @Test
     @Rollback(true)
     public void save_existingEntity() {
-        Region region = new Region();
+        JpaRegion region = new JpaRegion();
         region.setEntityId(1L);
         region.setRegionWidgets(new ArrayList<RegionWidget>());
-        Region saved = repository.save(region);
+        JpaRegion saved = (JpaRegion)repository.save(region);
         manager.flush();
         assertThat(saved, is(not(sameInstance(region))));
         assertThat(saved.getEntityId(), is(equalTo(region.getEntityId())));
@@ -95,29 +92,29 @@
 
     @Test
     public void save_cascadePersist() {
-        Region region = new Region();
+        JpaRegion region = new JpaRegion();
         region.setRegionWidgets(new ArrayList<RegionWidget>());
-        RegionWidget regionWidget = new RegionWidget();
+        RegionWidget regionWidget = new JpaRegionWidget();
         region.getRegionWidgets().add(regionWidget);
 
-        Region saved = repository.save(region);
+        JpaRegion saved = (JpaRegion)repository.save(region);
         manager.flush();
 
         assertThat(saved.getRegionWidgets().size(), is(equalTo(1)));
         RegionWidget actual = saved.getRegionWidgets().get(0);
 
         assertThat(actual, is(sameInstance(regionWidget)));
-        assertThat(actual.getEntityId(), is(notNullValue()));
+        assertThat(actual.getId(), is(notNullValue()));
     }
 
     @Test
     public void save_cascadeMerge() {
 
-        Region region = new Region();
+        JpaRegion region = new JpaRegion();
         region.setEntityId(1L);
         region.setRegionWidgets(new ArrayList<RegionWidget>());
-        RegionWidget regionWidget = new RegionWidget();
-        regionWidget.setEntityId(1L);
+        RegionWidget regionWidget = new JpaRegionWidget();
+        regionWidget.setId(1L);
         region.getRegionWidgets().add(regionWidget);
 
         Region saved = repository.save(region);
@@ -127,18 +124,18 @@
         RegionWidget actual = saved.getRegionWidgets().get(0);
 
         assertThat(actual, is(not(sameInstance(regionWidget))));
-        assertThat(actual.getEntityId(), is(equalTo(1L)));
+        assertThat(actual.getId(), is(equalTo(1L)));
     }
 
     @Test
     public void save_cascadeOrphan() {
-        Region region = repository.get(1L);
-        long id = region.getRegionWidgets().get(0).getEntityId();
+        JpaRegion region = (JpaRegion)repository.get(1L);
+        long id = region.getRegionWidgets().get(0).getId();
         region.getRegionWidgets().remove(0);
 
         Region saved = repository.save(region);
         manager.flush();
-        RegionWidget widget = manager.find(RegionWidget.class, id);
+        RegionWidget widget = manager.find(JpaRegionWidget.class, id);
 
         assertThat(saved.getRegionWidgets().size(), is(equalTo(1)));
         assertThat(widget, is(nullValue()));
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepositoryTest.java
similarity index 77%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepositoryTest.java
index c84d1e4..4319855 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaRegionWidgetRepositoryTest.java
@@ -19,8 +19,11 @@
 

 package org.apache.rave.portal.repository.impl;

 

+import org.apache.rave.portal.model.JpaRegionWidget;

+import org.apache.rave.portal.model.JpaRegionWidgetPreference;

 import org.apache.rave.portal.model.RegionWidget;

 import org.apache.rave.portal.model.RegionWidgetPreference;

+import org.apache.rave.portal.repository.RegionWidgetRepository;

 import org.junit.Test;

 import org.junit.runner.RunWith;

 import org.springframework.beans.factory.annotation.Autowired;

@@ -33,13 +36,7 @@
 import javax.persistence.PersistenceContext;

 import java.util.ArrayList;

 

-import org.apache.rave.portal.repository.RegionWidgetRepository;

-import static org.hamcrest.CoreMatchers.equalTo;

-import static org.hamcrest.CoreMatchers.is;

-import static org.hamcrest.CoreMatchers.not;

-import static org.hamcrest.CoreMatchers.notNullValue;

-import static org.hamcrest.CoreMatchers.nullValue;

-import static org.hamcrest.CoreMatchers.sameInstance;

+import static org.hamcrest.CoreMatchers.*;

 import static org.junit.Assert.assertThat;

 

 @Transactional

@@ -61,7 +58,7 @@
     public void getById_validId() {

         RegionWidget regionWidget = repository.get(VALID_REGION_WIDGET_ID);

         assertThat(regionWidget, is(notNullValue()));

-        assertThat(regionWidget.getEntityId(), is(equalTo(VALID_REGION_WIDGET_ID)));

+        assertThat(regionWidget.getId(), is(equalTo(VALID_REGION_WIDGET_ID)));

     }

 

     @Test

@@ -73,34 +70,34 @@
     @Test

     @Rollback(true)

     public void save_newEntity() {

-        RegionWidget regionWidget = new RegionWidget();

+        RegionWidget regionWidget = new JpaRegionWidget();

         regionWidget.setPreferences(new ArrayList<RegionWidgetPreference>());

 

         RegionWidget saved = repository.save(regionWidget);

         manager.flush();

         assertThat(saved, is(sameInstance(regionWidget)));

-        assertThat(saved.getEntityId(), is(notNullValue()));

+        assertThat(saved.getId(), is(notNullValue()));

     }

 

     @Test

     @Rollback(true)

     public void save_existingEntity() {

-        RegionWidget regionWidget = new RegionWidget();

-        regionWidget.setEntityId(VALID_REGION_WIDGET_ID);

+        RegionWidget regionWidget = new JpaRegionWidget();

+        regionWidget.setId(VALID_REGION_WIDGET_ID);

         regionWidget.setPreferences(new ArrayList<RegionWidgetPreference>());

 

         RegionWidget saved = repository.save(regionWidget);

         manager.flush();

         assertThat(saved, is(not(sameInstance(regionWidget))));

-        assertThat(saved.getEntityId(), is(equalTo(regionWidget.getEntityId())));

+        assertThat(saved.getId(), is(equalTo(regionWidget.getId())));

     }

 

     @Test

     @Rollback(true)

     public void save_cascadePersist() {

-        RegionWidget regionWidget = new RegionWidget();

+        RegionWidget regionWidget = new JpaRegionWidget();

         regionWidget.setPreferences(new ArrayList<RegionWidgetPreference>());

-        RegionWidgetPreference regionWidgetPreference = new RegionWidgetPreference(null, null, VALID_PREFERENCE_NAME,

+        RegionWidgetPreference regionWidgetPreference = new JpaRegionWidgetPreference(null, null, VALID_PREFERENCE_NAME,

                 VALID_PREFERENCE_VALUE);

         regionWidget.getPreferences().add(regionWidgetPreference);

 

@@ -108,7 +105,7 @@
         manager.flush();

 

         assertThat(saved.getPreferences().size(), is(equalTo(1)));

-        RegionWidgetPreference actual = saved.getPreferences().get(0);

+        JpaRegionWidgetPreference actual = (JpaRegionWidgetPreference)saved.getPreferences().get(0);

 

         assertThat(actual, is(sameInstance(regionWidgetPreference)));

         assertThat(actual.getEntityId(), is(notNullValue()));

@@ -119,10 +116,10 @@
     public void save_cascadeMerge() {

         long VALID_PREFERENCE_ID = addPreferenceToRegionWidget(VALID_REGION_WIDGET_ID);

 

-        RegionWidget regionWidget = new RegionWidget();

-        regionWidget.setEntityId(VALID_REGION_WIDGET_ID);

+        RegionWidget regionWidget = new JpaRegionWidget();

+        regionWidget.setId(VALID_REGION_WIDGET_ID);

         regionWidget.setPreferences(new ArrayList<RegionWidgetPreference>());

-        RegionWidgetPreference regionWidgetPreference = new RegionWidgetPreference(VALID_PREFERENCE_ID,

+        JpaRegionWidgetPreference regionWidgetPreference = new JpaRegionWidgetPreference(VALID_PREFERENCE_ID,

                 VALID_REGION_WIDGET_ID, VALID_PREFERENCE_NAME, VALID_PREFERENCE_VALUE);

         regionWidget.getPreferences().add(regionWidgetPreference);

 

@@ -130,7 +127,7 @@
         manager.flush();

 

         assertThat(saved.getPreferences().size(), is(equalTo(1)));

-        RegionWidgetPreference actual = saved.getPreferences().get(0);

+        JpaRegionWidgetPreference actual = (JpaRegionWidgetPreference)saved.getPreferences().get(0);

 

         assertThat(actual, is(not(sameInstance(regionWidgetPreference))));

         assertThat(actual.getEntityId(), is(equalTo(regionWidgetPreference.getEntityId())));

@@ -146,7 +143,7 @@
 

         RegionWidget saved = repository.save(regionWidget);

         manager.flush();

-        RegionWidgetPreference preference = manager.find(RegionWidgetPreference.class, VALID_PREFERENCE_ID);

+        RegionWidgetPreference preference = manager.find(JpaRegionWidgetPreference.class, VALID_PREFERENCE_ID);

 

         assertThat(saved.getPreferences().size(), is(equalTo(0)));

         assertThat(preference, is(nullValue()));

@@ -154,12 +151,12 @@
 

     private long addPreferenceToRegionWidget(long validRegionWidgetId) {

         RegionWidget regionWidget = repository.get(validRegionWidgetId);

-        RegionWidgetPreference regionWidgetPreference = new RegionWidgetPreference(null, validRegionWidgetId,

+        RegionWidgetPreference regionWidgetPreference = new JpaRegionWidgetPreference(null, validRegionWidgetId,

                 VALID_PREFERENCE_NAME, VALID_PREFERENCE_VALUE);

         regionWidget.getPreferences().add(regionWidgetPreference);

 

         RegionWidget saved = repository.save(regionWidget);

         manager.flush();

-        return saved.getPreferences().get(0).getEntityId();

+        return ((JpaRegionWidgetPreference)saved.getPreferences().get(0)).getEntityId();

     }

 }
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaTagRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaTagRepositoryTest.java
new file mode 100644
index 0000000..f6a85fa
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaTagRepositoryTest.java
@@ -0,0 +1,157 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.repository.impl;

+

+import org.apache.rave.portal.model.JpaTag;

+import org.apache.rave.portal.model.Tag;

+import org.apache.rave.portal.model.impl.TagImpl;

+import org.apache.rave.portal.model.WidgetTag;

+import org.apache.rave.portal.repository.TagRepository;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.annotation.Rollback;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+import org.springframework.transaction.annotation.Transactional;

+

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

+import java.util.ArrayList;

+import java.util.List;

+

+import static org.junit.Assert.*;

+

+/**

+ *

+ */

+@Transactional

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaTagRepositoryTest {

+

+    @PersistenceContext

+    private EntityManager manager;

+

+    @Autowired

+    private TagRepository repository;

+

+

+    private static final Long VALID_ID = 1L;

+

+    @Test

+    public void getById_validId() {

+        final Tag tag = repository.get(VALID_ID);

+        assertNotNull(tag);

+        assertEquals(VALID_ID, ((JpaTag)tag).getEntityId());

+        assertEquals(tag.getKeyword(), "news");

+    }

+

+    @Test

+    public void getList() {

+        List<Tag> list = repository.getAll();

+        assertTrue(list.size() == 3);

+        assertEquals(list.iterator().next().getKeyword(), "misc");

+        assertTrue(list.iterator().next().getWidgets().size() == 0);

+    }

+

+    @Test

+    public void countAll() {

+        int count = repository.getCountAll();

+        assertTrue("Found at least 1 tag", count == 3);

+    }

+

+    @Test

+    public void getByKeyword() {

+        Tag tag = repository.getByKeyword("news");

+        assertNotNull(tag);

+        assertTrue(((JpaTag)tag).getEntityId() == 1);

+        tag = repository.getByKeyword("NEWS");

+        assertNotNull(tag);

+        assertTrue(((JpaTag)tag).getEntityId() == 1);

+        tag = repository.getByKeyword("news  ");

+        assertNotNull(tag);

+        assertTrue(((JpaTag)tag).getEntityId() == 1);

+        tag = repository.getByKeyword("   news  ");

+        assertNotNull(tag);

+        assertTrue(((JpaTag)tag).getEntityId() == 1);

+    }

+

+    @Test

+    @Transactional

+    @Rollback(true)

+    public void save_valid(){

+        Tag tag = new JpaTag();

+        String ordnance = "ordnance";

+        tag.setKeyword(ordnance);

+        tag.setWidgets(new ArrayList<WidgetTag>());

+        repository.save(tag);

+        Tag foundTag = repository.getByKeyword(ordnance);

+        assertNotNull(foundTag);

+        assertEquals(tag.getKeyword(), foundTag.getKeyword());

+        assertEquals(tag.getWidgets().size(), foundTag.getWidgets().size());

+    }

+

+    @Test(expected = NullPointerException.class)

+    @Transactional

+    @Rollback(true)

+    public void save_null(){

+        Tag tag = null;

+        tag = repository.save(tag);

+        assertNull(tag);

+    }

+

+    @Test

+    @Transactional

+    @Rollback(true)

+    public void delete_valid_jpaTag(){

+        String keyword = "misc";

+        JpaTag jpaTag = (JpaTag)repository.getByKeyword(keyword);

+        assertNotNull(jpaTag);

+        repository.delete(jpaTag);

+        assertNull(repository.getByKeyword(keyword));

+    }

+

+    @Test

+    @Transactional

+    @Rollback(true)

+    public void delete_valid_tagImpl(){

+        String keyword = "misc";

+        // make sure we do have a tag with the keyword in the db

+        JpaTag control = (JpaTag)repository.getByKeyword(keyword);

+        assertNotNull(control);

+        // create a tag with the keyword not of JpaTag.class for branch coverage

+        TagImpl tag = new TagImpl(keyword);

+        assertNotNull(tag);

+        repository.delete(tag);

+        assertNull(repository.getByKeyword(keyword));

+    }

+

+    @Test

+    @Transactional

+    @Rollback(true)

+    public void delete_invalid(){

+        String keyword = "abdhjdhlnews";

+        TagImpl tag = new TagImpl(keyword);

+        assertNotNull(tag);

+        repository.delete(tag);

+    }

+

+}

diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaUserRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaUserRepositoryTest.java
similarity index 93%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaUserRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaUserRepositoryTest.java
index aadaf7d..46be940 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaUserRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaUserRepositoryTest.java
@@ -21,24 +21,20 @@
 
 import junit.framework.Assert;
 import org.apache.rave.portal.model.Authority;
-import org.apache.rave.portal.model.Page;
+import org.apache.rave.portal.model.JpaUser;
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.repository.AuthorityRepository;
 import org.apache.rave.portal.repository.UserRepository;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.bcrypt.BCrypt;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.test.annotation.Rollback;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
 import java.util.List;
 
 import static org.hamcrest.CoreMatchers.*;
@@ -87,7 +83,7 @@
 
     @Test
     public void getByUsername_valid() {
-        User user = repository.getByUsername(USER_NAME);
+        JpaUser user = (JpaUser)repository.getByUsername(USER_NAME);
         assertThat(user, notNullValue());
         assertThat(user.getEntityId(), is(equalTo(USER_ID)));
         assertThat(true, is(passwordEncoder.matches(USER_NAME, user.getPassword())));
@@ -103,7 +99,7 @@
 
     @Test
     public void getByUserEmail_valid() {
-        User user = repository.getByUserEmail(USER_EMAIL);
+        JpaUser user = (JpaUser)repository.getByUserEmail(USER_EMAIL);
         assertThat(user, notNullValue());
         assertThat(user.getEntityId(), is(equalTo(USER_ID)));
         assertThat(true, is(passwordEncoder.matches(USER_NAME, user.getPassword())));
@@ -117,7 +113,7 @@
         Assert.assertNotNull("Existing authority", authority);
 
         int usercount = authority.getUsers().size();
-        User user = new User();
+        User user = new JpaUser();
         user.setUsername("dummy");
         authority.addUser(user);
         authorityRepository.save(authority);
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepositoryTest.java
similarity index 100%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetCommentRepositoryTest.java
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepositoryTest.java
similarity index 95%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepositoryTest.java
index c56b002..7e2df8d 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRatingRepositoryTest.java
@@ -19,7 +19,7 @@
 
 package org.apache.rave.portal.repository.impl;
 
-import org.apache.rave.portal.model.WidgetRating;
+import org.apache.rave.portal.model.JpaWidgetRating;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -62,7 +62,7 @@
 
     @Test
     public void getByWidgetIdAndUserId_missing() {
-        assertThat(repository.getByWidgetIdAndUserId(INVALID_WIDGET_ID, INVALID_USER_ID), is(nullValue(WidgetRating.class)));       
+        assertThat(repository.getByWidgetIdAndUserId(INVALID_WIDGET_ID, INVALID_USER_ID), is(nullValue()));
     }
 
     @Test
diff --git a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRepositoryTest.java
similarity index 87%
rename from rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRepositoryTest.java
rename to rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRepositoryTest.java
index 28f2c41..d7087c6 100644
--- a/rave-components/rave-core/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRepositoryTest.java
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetRepositoryTest.java
@@ -62,7 +62,7 @@
 
     @Test
     public void getById_valid() {
-        Widget widget = repository.get(1L);
+        JpaWidget widget = (JpaWidget)repository.get(1L);
         assertThat(widget, is(notNullValue()));
         assertThat(widget.getEntityId(), is(equalTo(1L)));
     }
@@ -175,14 +175,14 @@
 
     @Test
     public void getByOwner() {
-        final User user = new User(2L);
+        final User user = new JpaUser(2L);
         List<Widget> widgets = repository.getByOwner(user, 0, 10);
         assertEquals(1, widgets.size());
     }
 
     @Test
     public void getCountByOwner() {
-        final User user = new User(2L);
+        final User user = new JpaUser(2L);
         assertEquals(1, repository.getCountByOwner(user, 0, 10));
     }
 
@@ -196,12 +196,12 @@
         Widget doesnotexist = repository.getByUrl(url);
         assertNull(doesnotexist);
 
-        Widget widget = new Widget();
+        Widget widget = new JpaWidget();
         widget.setTitle("Widget with long description");
         widget.setUrl(url);
         widget.setDescription(longDescription);
         widget = repository.save(widget);
-        assertNotNull(widget.getEntityId());
+        assertNotNull(widget.getId());
         assertEquals(longDescription, widget.getDescription());
     }
 
@@ -227,21 +227,21 @@
         Map<Long, WidgetRating> widgetRatings = repository.getUsersWidgetRatings(1L);
 
         WidgetRating gadgetOne = widgetRatings.get(1L);
-        assertEquals(WidgetRating.DISLIKE, gadgetOne.getScore());
+        assertEquals(JpaWidgetRating.DISLIKE, gadgetOne.getScore());
         assertEquals(new Long(1), gadgetOne.getUserId());
-        assertEquals(new Long(1), gadgetOne.getEntityId());
+        assertEquals(new Long(1), gadgetOne.getId());
 
         WidgetRating gadgetTwo = widgetRatings.get(2L);
-        assertEquals(WidgetRating.LIKE, gadgetTwo.getScore());
+        assertEquals(JpaWidgetRating.LIKE, gadgetTwo.getScore());
         assertEquals(new Long(1), gadgetTwo.getUserId());
-        assertEquals(new Long(2), gadgetTwo.getEntityId());
+        assertEquals(new Long(2), gadgetTwo.getId());
     }
 
     @Test
     public void getEmptyUserWidgetStatistics() {
         //ensure that a bogus user has only UNSET widget ratings
         for (Map.Entry<Long, WidgetStatistics> entry : repository.getAllWidgetStatistics(Long.MAX_VALUE).entrySet()) {
-            assertEquals(WidgetRating.UNSET.intValue(), entry.getValue().getUserRating());
+            assertEquals(JpaWidgetRating.UNSET.intValue(), entry.getValue().getUserRating());
         }
     }
 
@@ -252,13 +252,13 @@
         assertNotNull(ratings);
         assertEquals(1, ratings.size());
 
-        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getEntityId(), 1L);
+        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getId(), 1L);
         widgetStatistics.toString();
         assertNotNull(widgetStatistics);
         assertEquals(0, widgetStatistics.getTotalLike());
         assertEquals(1, widgetStatistics.getTotalDislike());
         assertEquals(10, widgetStatistics.getTotalUserCount());
-        assertEquals(WidgetRating.DISLIKE.intValue(), widgetStatistics.getUserRating());
+        assertEquals(JpaWidgetRating.DISLIKE.intValue(), widgetStatistics.getUserRating());
     }
 
     @Test
@@ -268,12 +268,12 @@
         assertNotNull(ratings);
         assertEquals(1, ratings.size());
 
-        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getEntityId(), 1L);
+        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getId(), 1L);
         assertNotNull(widgetStatistics);
         assertEquals(1, widgetStatistics.getTotalLike());
         assertEquals(0, widgetStatistics.getTotalDislike());
         assertEquals(10, widgetStatistics.getTotalUserCount());
-        assertEquals(WidgetRating.LIKE.intValue(), widgetStatistics.getUserRating());
+        assertEquals(JpaWidgetRating.LIKE.intValue(), widgetStatistics.getUserRating());
     }
 
     @Test
@@ -283,23 +283,23 @@
         assertNotNull(ratings);
         assertEquals(0, ratings.size());
 
-        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getEntityId(), 1L);
+        WidgetStatistics widgetStatistics = repository.getWidgetStatistics(widget.getId(), 1L);
         assertNotNull(widgetStatistics);
         assertEquals(0, widgetStatistics.getTotalDislike());
         assertEquals(0, widgetStatistics.getTotalLike());
-        assertEquals(WidgetRating.UNSET.intValue(), widgetStatistics.getUserRating());
+        assertEquals(JpaWidgetRating.UNSET.intValue(), widgetStatistics.getUserRating());
     }
 
     @Test
     @Transactional(readOnly = false)
-    @Rollback    
+    @Rollback
     public void addWidgetRating() {
         Widget widget = repository.get(3L);
         assertNotNull(widget.getRatings());
-        WidgetRating widgetRating = new WidgetRating();
+        WidgetRating widgetRating = new JpaWidgetRating();
         widgetRating.setScore(10);
         widgetRating.setUserId(1L);
-        widgetRating.setWidgetId(widget.getEntityId());
+        widgetRating.setWidgetId(widget.getId());
         widget.getRatings().add(widgetRating);
 
         repository.save(widget);
@@ -312,19 +312,19 @@
         assertNotNull(reloadedWidgetRating);
         assertEquals(widgetRating.getScore(), reloadedWidgetRating.getScore());
         assertEquals(widgetRating.getUserId(), reloadedWidgetRating.getUserId());
-        assertEquals(widget.getEntityId(), reloadedWidgetRating.getWidgetId());
+        assertEquals(widget.getId(), reloadedWidgetRating.getWidgetId());
     }
 
     @Test
     @Transactional(readOnly = false)
-    @Rollback    
+    @Rollback
     public void updateWidgetRating() {
         Widget widget = repository.get(4L);
         assertNotNull(widget.getRatings());
-        WidgetRating widgetRating = new WidgetRating();
+        WidgetRating widgetRating = new JpaWidgetRating();
         widgetRating.setScore(10);
         widgetRating.setUserId(1L);
-        widgetRating.setWidgetId(widget.getEntityId());
+        widgetRating.setWidgetId(widget.getId());
         widget.getRatings().add(widgetRating);
 
         repository.save(widget);
@@ -337,7 +337,7 @@
         assertNotNull(reloadedWidgetRating);
         assertEquals(widgetRating.getScore(), reloadedWidgetRating.getScore());
         assertEquals(widgetRating.getUserId(), reloadedWidgetRating.getUserId());
-        assertEquals(widget.getEntityId(), reloadedWidgetRating.getWidgetId());
+        assertEquals(widget.getId(), reloadedWidgetRating.getWidgetId());
 
         reloadedWidgetRating.setScore(0);
 
@@ -350,7 +350,7 @@
         assertNotNull(reloadedWidgetRating);
         assertEquals(widgetRating.getScore(), reloadedWidgetRating.getScore());
         assertEquals(widgetRating.getUserId(), reloadedWidgetRating.getUserId());
-        assertEquals(widget.getEntityId(), reloadedWidgetRating.getWidgetId());
+        assertEquals(widget.getId(), reloadedWidgetRating.getWidgetId());
     }
 
     @Test
@@ -368,13 +368,13 @@
       String tag = "news";
         List<Widget> widgets = repository.getWidgetsByTag(tag, 0, 10);
         assertTrue(widgets.size() == 1);
-        assertTrue(widgets.iterator().next().getEntityId() == 3);
+        assertTrue(widgets.iterator().next().getId() == 3);
         assertTrue(repository.getCountByTag(tag) == 1);
 
         tag = "wikipedia";
         widgets = repository.getWidgetsByTag(tag, 0, 10);
         assertTrue(widgets.size() == 1);
-        assertTrue(widgets.iterator().next().getEntityId() == 1);
+        assertTrue(widgets.iterator().next().getId() == 1);
         assertTrue(repository.getCountByTag(tag) == 1);
 
         tag = "aaanews";
@@ -384,19 +384,19 @@
 
         widgets = repository.getWidgetsByTag("NEWS", 0, 10);
         assertTrue(widgets.size() == 1);
-        assertTrue(widgets.iterator().next().getEntityId() == 3);
+        assertTrue(widgets.iterator().next().getId() == 3);
         assertTrue(repository.getCountByTag("NEWS") == 1);
     }
 
     @Test
     @Transactional(readOnly = false)
-    @Rollback    
+    @Rollback
     public void addWidgetCategory() {
         final long WIDGET_ID = 1L;
-        final User user = new User(1L);
+        final User user = new JpaUser(1L);
 
-        Category category = new Category();
-        category.setEntityId(1L);
+        Category category = new JpaCategory();
+        category.setId(1L);
         category.setText("Sample Category");
         category.setCreatedUser(user);
         category.setCreatedDate(new Date());
@@ -404,31 +404,30 @@
         category.setLastModifiedDate(new Date());
         sharedManager.merge(category);
 
-
-        Widget widget = repository.get(WIDGET_ID);        
+        Widget widget = repository.get(WIDGET_ID);
         assertThat(widget.getCategories().size(), is(2));
 
-        widget.getCategories().add(category);                
+        widget.getCategories().add(category);
         repository.save(widget);
-        
+
         Widget reloadedWidget = repository.get(WIDGET_ID);
         assertThat(reloadedWidget.getCategories().size(), is(3));
-        
+
         // test that category is in list
         boolean foundNewCategory = false;
         for (Category c : reloadedWidget.getCategories()) {
-            if (c.getEntityId().equals(WIDGET_ID)) {
+            if (c.getId().equals(WIDGET_ID)) {
                 foundNewCategory = true;
                 break;
             }
         }
-        
+
         assertThat(foundNewCategory, is(true));
     }
 
     @Test
     @Transactional(readOnly = false)
-    @Rollback    
+    @Rollback
     public void removeWidgetCategory() {
         final long WIDGET_ID = 1L;
 
@@ -440,7 +439,7 @@
 
         Widget reloadedWidget = repository.get(WIDGET_ID);
         assertThat(reloadedWidget.getCategories().size(), is(1));
-        assertThat(reloadedWidget.getCategories().get(0).getEntityId(), is(4L));
+        assertThat(reloadedWidget.getCategories().get(0).getId(), is(4L));
     }
 
     @Test
@@ -450,12 +449,12 @@
         final long WIDGET_ID = 2L;
         final long USER_ID = 1L;
         final int NUM_WIDGETS_OWNED_BY_USER = 16;
-        
+
         Widget widget = repository.get(WIDGET_ID);
-        assertThat(widget.getOwner().getEntityId(), is(USER_ID));        
+        assertThat(widget.getOwner().getId(), is(USER_ID));
         assertThat(repository.unassignWidgetOwner(USER_ID), is(NUM_WIDGETS_OWNED_BY_USER));
         sharedManager.flush();
         sharedManager.refresh(widget);
-        assertThat(widget.getOwner(), is(nullValue(User.class)));
+        assertThat(widget.getOwner(), is(nullValue()));
     }
 }
diff --git a/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepositoryTest.java b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepositoryTest.java
new file mode 100644
index 0000000..d953279
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/java/org/apache/rave/portal/repository/impl/JpaWidgetTagRepositoryTest.java
@@ -0,0 +1,156 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you 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.rave.portal.repository.impl;

+

+import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.repository.WidgetTagRepository;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.springframework.beans.factory.annotation.Autowired;

+import org.springframework.test.annotation.Rollback;

+import org.springframework.test.context.ContextConfiguration;

+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

+import org.springframework.transaction.annotation.Transactional;

+

+import javax.persistence.EntityManager;

+import javax.persistence.PersistenceContext;

+

+import java.util.Date;

+

+import static org.junit.Assert.*;

+

+/**

+ *

+ */

+@Transactional

+@RunWith(SpringJUnit4ClassRunner.class)

+@ContextConfiguration(locations = {"classpath:test-dataContext.xml", "classpath:test-applicationContext.xml"})

+public class JpaWidgetTagRepositoryTest {

+

+    @PersistenceContext

+    private EntityManager manager;

+

+    @Autowired

+    private WidgetTagRepository repository;

+

+    @Test

+    public void getByWidgetIdAndTag_valid(){

+        Long widgetId = 3L;

+        String keyword = "news";

+        JpaWidgetTag jpaWidgetTag = (JpaWidgetTag)repository.getByWidgetIdAndTag(widgetId, keyword);

+        assertNotNull(jpaWidgetTag);

+        assertEquals(widgetId, jpaWidgetTag.getWidgetId());

+        assertEquals(keyword, jpaWidgetTag.getTag().getKeyword());

+    }

+

+    @Test

+    public void getByWidgetIdAndTag_keyword_trim_valid(){

+        Long widgetId = 3L;

+        String keyword = "  news    ";

+        JpaWidgetTag jpaWidgetTag = (JpaWidgetTag)repository.getByWidgetIdAndTag(widgetId, keyword);

+        assertNotNull(jpaWidgetTag);

+        assertEquals(widgetId, jpaWidgetTag.getWidgetId());

+        assertEquals(keyword.trim(), jpaWidgetTag.getTag().getKeyword());

+    }

+

+    @Test

+    public void getByWidgetIdAndTag_invalid(){

+        Long widgetId = 3L;

+        String keyword = "saturday";

+        JpaWidgetTag jpaWidgetTag = (JpaWidgetTag)repository.getByWidgetIdAndTag(widgetId, keyword);

+        assertNull(jpaWidgetTag);

+    }

+    

+    @Test

+    public void get_valid(){

+        Long id = 1L;

+        JpaWidgetTag widgetTag = (JpaWidgetTag)repository.get(id);

+        assertNotNull(widgetTag);

+        assertEquals(id, widgetTag.getEntityId());

+    }

+    

+    @Test

+    public void get_invalid(){

+        Long id = 1000291L;

+        JpaWidgetTag jpaWidgetTag = (JpaWidgetTag)repository.get(id);

+        assertNull(jpaWidgetTag);

+    }

+

+    @Test

+    @Transactional

+    @Rollback(true)

+    public void save() {

+        WidgetTag widgetTag = new JpaWidgetTag();

+        JpaTag tag = new JpaTag(null, "boing");

+        widgetTag.setTag(tag);

+        widgetTag.setWidgetId(2L);

+        widgetTag.setCreatedDate(new Date());

+        widgetTag.setUser(new JpaUser());

+        JpaWidgetTag jpaWidgetTag = (JpaWidgetTag)repository.save(widgetTag);

+        assertNotNull(jpaWidgetTag);

+        assertEquals(widgetTag.getTag().getKeyword(), jpaWidgetTag.getTag().getKeyword());

+        assertEquals(widgetTag.getWidgetId(), jpaWidgetTag.getWidgetId());

+        assertEquals(widgetTag.getUser(), jpaWidgetTag.getUser());

+        assertEquals(widgetTag.getCreatedDate(), jpaWidgetTag.getCreatedDate());

+        assertEquals(JpaWidgetTag.class, jpaWidgetTag.getClass());

+    }

+

+    @Test(expected = NullPointerException.class)

+    @Transactional

+    @Rollback(true)

+    public void save_null() {

+        WidgetTag widgetTag = null;

+        JpaWidgetTag jpaWidgetTag = (JpaWidgetTag)repository.save(widgetTag);

+        assertNull(jpaWidgetTag);

+    }

+    

+    @Test

+    @Transactional

+    @Rollback(true)

+    public void delete_valid(){

+        Long id = 1L;

+        WidgetTag widgetTag = repository.get(id);

+        assertNotNull(widgetTag);

+        repository.delete(widgetTag);

+        assertNull(repository.get(id));

+    }

+

+    @Test

+    @Transactional

+    @Rollback(true)

+    public void delete_jpaWidgetTag_valid(){

+        Long id = 1L;

+        JpaWidgetTag jpaWidgetTag = (JpaWidgetTag)repository.get(id);

+        assertNotNull(jpaWidgetTag);

+        repository.delete(jpaWidgetTag);

+        assertNull(repository.get(id));

+    }

+

+    @Test(expected = NullPointerException.class)

+    @Transactional

+    @Rollback(true)

+    public void delete_invalid(){

+        Long id = 17827873261L;

+        WidgetTag widgetTag = repository.get(id);

+        assertNull(widgetTag);

+        repository.delete(widgetTag);

+        assertNull(repository.get(id));

+    }

+}

diff --git a/rave-components/rave-jpa/src/test/resources/log4j.xml b/rave-components/rave-jpa/src/test/resources/log4j.xml
new file mode 100644
index 0000000..5576a90
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/resources/log4j.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+  
+  $Id$
+-->
+<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER" "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+  <!-- Appenders -->
+  <appender name="console" class="org.apache.log4j.ConsoleAppender">
+    <param name="Target" value="System.out" />
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%-5p: %c - %m%n" />
+    </layout>
+  </appender>
+
+  <!-- Springframework logger -->
+  <logger name="org.springframework">
+    <level value="info" />
+  </logger>
+
+  <!-- Rave logger -->
+  <logger name="org.apache.rave">
+    <level value="debug" />
+  </logger>
+  
+  <!-- Root Logger -->
+  <root>
+    <priority value="warn" />
+    <appender-ref ref="console" />
+  </root>
+    
+</log4j:configuration>
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/resources/portal.properties b/rave-components/rave-jpa/src/test/resources/portal.properties
new file mode 100644
index 0000000..c563093
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/resources/portal.properties
@@ -0,0 +1,69 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+# the default page name to create for new users
+portal.page.default_name=Main
+
+#Default Rave Portal database settings with in memory H2 database
+portal.dataSource.url=jdbc:h2:mem:portal;DB_CLOSE_DELAY=-1
+portal.dataSource.driver=org.h2.Driver
+portal.dataSource.username=sa
+portal.dataSource.password=local
+
+portal.jpaDialect=org.apache.rave.persistence.jpa.impl.H2OpenJpaDialect
+portal.jpaVendorAdapter.databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary
+portal.jpaVendorAdapter.database=H2
+
+# General Rave portal database settings
+portal.jpaVendorAdapter.showSql=true
+portal.openjpa.Log=DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=WARN
+portal.openjpa.RuntimeUnenhancedClasses=supported
+portal.openjpa.jdbc.SynchronizeMappings=buildSchema(ForeignKeys=true)
+portal.openjpa.jdbc.MappingDefaults=ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict
+
+provider.wookie.wookieServerUrl=http://localhost:8080/wookie
+provider.wookie.wookieApiKey=TEST
+# captcha settings
+portal.captcha.enabled=false
+portal.captcha.key.private=
+portal.captcha.key.public=
+portal.captcha.usenoscript=false
+portal.captcha.invalid.configuration=<label class="error">ReCaptcha service is not properly configured.</label>
+
+#mail settings
+portal.mail.sender=
+portal.mail.replyto=
+portal.mail.host=
+portal.mail.password=
+portal.mail.username=
+portal.mail.protocol=smtp
+portal.mail.port=25
+portal.mail.username.subject=Rave username reminder service
+portal.mail.username.template=username_reminder.ftl
+portal.mail.passwordservice.subject=Rave password reminder service
+portal.mail.passwordservice.template=password_reminder.ftl
+portal.mail.passwordservice.valid.minutes=30
+portal.mail.service.baseurl=http://localhost:8080/portal/app/changepassword/
+
+# Account approval
+portal.user.account.needapproval=false
+portal.user.account.admin.email=
+portal.user.account.admin.subject=Rave User Approval
+portal.user.account.admin.template=admin_approval.ftl
+portal.mail.service.loginpage=http://localhost:8080/portal/
diff --git a/rave-components/rave-jpa/src/test/resources/test-applicationContext.xml b/rave-components/rave-jpa/src/test/resources/test-applicationContext.xml
new file mode 100644
index 0000000..b3c3193
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/resources/test-applicationContext.xml
@@ -0,0 +1,26 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
+
+    <import resource="classpath:org/apache/rave/jpa-applicationContext.xml"/>
+
+</beans>
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/resources/test-dataContext.xml b/rave-components/rave-jpa/src/test/resources/test-dataContext.xml
new file mode 100644
index 0000000..80c0fa4
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/resources/test-dataContext.xml
@@ -0,0 +1,32 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
+
+    <bean id="dataSourcePopulator" class="org.apache.rave.jdbc.util.DataSourcePopulator">
+        <property name="executeScriptQuery" value="SELECT * FROM WIDGET"/>
+        <property name="scriptLocations">
+            <list>
+                <value>classpath:test_data.sql</value>
+            </list>
+        </property>
+    </bean>
+</beans>
\ No newline at end of file
diff --git a/rave-components/rave-jpa/src/test/resources/test_data.sql b/rave-components/rave-jpa/src/test/resources/test_data.sql
new file mode 100644
index 0000000..a7e8389
--- /dev/null
+++ b/rave-components/rave-jpa/src/test/resources/test_data.sql
@@ -0,0 +1,1231 @@
+ -- Licensed to the Apache Software Foundation (ASF) under one
+ -- or more contributor license agreements.  See the NOTICE file
+ -- distributed with this work for additional information
+ -- regarding copyright ownership.  The ASF licenses this file
+ -- to you 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.
+
+
+
+ -- ***********************************************************************************
+ -- The initial data is used for demo and test purposes with an in memory H2 database.
+ -- It is not guaranteed that the queries will work on other database systems.
+ -- ***********************************************************************************
+
+ -- ***********************************************************************************
+-- Manually create table indices
+set @page_seq = 'page';
+set @page_layout_seq = 'page_layout';
+set @region_seq = 'region';
+set @region_widget_seq = 'region_widget';
+set @user_seq = 'person';
+set @widget_seq = 'widget';
+set @granted_authority_seq = 'granted_authority';
+set @widget_comment_seq = 'widget_comment';
+set @widget_rating_seq = 'widget_rating';
+set @portal_preference_seq = 'portal_preference';
+set @tag_seq = 'tag';
+set @widget_tag_seq = 'widget_tag';
+set @category_seq = 'category';
+set @page_template_seq = 'page_template';
+set @page_template_region_seq = 'page_template_region';
+set @page_template_widget_seq = 'page_template_widget';
+set @page_user_seq = 'page_user';
+set @token_info_seq = 'token_info';
+set @oauth_consumer_store_seq = 'oauth_consumer_store';
+set @application_data_seq = 'application_data';
+set @person_seq = 'person';
+set @person_association_seq = 'person_association';
+set @groups_seq = 'groups';
+set @group_members_seq = 'group_members';
+
+CREATE TABLE IF NOT EXISTS RAVE_PORTAL_SEQUENCES (seq_name VARCHAR(255) PRIMARY KEY NOT NULL, seq_count BIGINT(19));
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@page_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@page_layout_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@region_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@region_widget_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values ('region_widget_preference', 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@user_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@widget_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@widget_comment_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@widget_rating_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@granted_authority_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@portal_preference_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@tag_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@widget_tag_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@category_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@page_template_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@page_template_region_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@page_template_widget_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@page_user_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@person_association_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@groups_seq, 1);
+INSERT INTO RAVE_PORTAL_SEQUENCES(seq_name, seq_count) values (@group_members_seq, 1);
+
+CREATE TABLE IF NOT EXISTS RAVE_SHINDIG_SEQUENCES (seq_name VARCHAR(255) PRIMARY KEY NOT NULL, seq_count BIGINT(19));
+INSERT INTO RAVE_SHINDIG_SEQUENCES(seq_name, seq_count) values (@token_info_seq, 1);
+INSERT INTO RAVE_SHINDIG_SEQUENCES(seq_name, seq_count) values (@oauth_consumer_store_seq, 1);
+INSERT INTO RAVE_SHINDIG_SEQUENCES(seq_name, seq_count) values (@application_data_seq, 1);
+
+
+  -- ***********************************************************************************
+  -- start page layout data, required to make the portal work ---
+set @one_col_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@one_col_id, 'columns_1', 1, 0, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+
+set @two_col_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@two_col_id, 'columns_2', 2, 1, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+
+set @twown_col_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@twown_col_id, 'columns_2wn', 2, 2, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+
+set @three_col_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@three_col_id, 'columns_3', 3, 3, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+
+set @threewn_col_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@threewn_col_id, 'columns_3nwn', 3, 4, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+
+set @four_col_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@four_col_id, 'columns_4', 4, 5, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+
+set @fourwn_col_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@fourwn_col_id, 'columns_3nwn_1_bottom', 4, 6, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+
+set @person_profile_layout_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_layout_seq);
+insert into page_layout (entity_id, code,  number_of_regions, render_sequence, user_selectable)
+values (@person_profile_layout_id, 'person_profile', 1, 8, false);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_layout_seq;
+--- end page layout data ----
+
+
+  -- ***********************************************************************************
+  --- start user data ---
+set @user_id_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_1, 'canonical', '$2a$10$TkEgze5kLy9nRlfd8PT1zunh6P1ND8WPjLojFjAMNgZMu1D9D1n4.', FALSE, FALSE, TRUE,'canonical@example.com', @three_col_id, 'User', 'Canonical', 'Paul');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_2, 'john.doe', '$2a$10$8Dir7boy3UyVqy6erfj6WuQXUTf.ejTldPSsVIty7.pPT3Krkly26', FALSE, FALSE, TRUE,'john.doe@example.com', @three_col_id, 'User', 'Doe', 'John');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_3 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_3, 'jane.doe', '$2a$10$YP9cjZEA.gG/ng2YwTBIyucMpuiQ7Fvz0K8rOt14rIBhVwlOrh1tu', FALSE, FALSE, TRUE,'jane.doe@example.net', @three_col_id, 'User', 'Doe', 'Jane');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_4 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_4, 'george.doe', '$2a$10$0bcOUkQgAwE/qmdc1NcUveNzx/IYIcOUu4ydyT8DEicTCxGJF/vcW', FALSE, FALSE, TRUE,'george.doe@example.org', @three_col_id, 'User', 'Doe', 'George');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_5 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_5,'mario.rossi', '$2a$10$HZ6WHAKQCs8waLooL98l6.fLzwh3D8u/V0.UebIjojawfXJhX1DQ2', FALSE, FALSE, TRUE,'mario.rossi@example.com', @three_col_id, 'User', 'Rossi', 'Mario');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_6 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_6, 'maija.m', '$2a$10$3feYdjrW40hkqP4/xupKP.YMgdYmDsZZus./vK4FbBs9QZG2.FuNC', FALSE, FALSE, TRUE,'maijam@example.com', @three_col_id, 'User', 'M', 'Maija');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_7 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_7, 'one.col', '$2a$10$5VqE2YEqT75pCVjKqjP2b.gNGly9fsTVUOMQR/JEjkHSbqvA3A6IO', FALSE, FALSE, TRUE,'one.col@example.com', @three_col_id, 'User', 'Column', 'One');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_8 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_8, 'twown.col', '$2a$10$Inpufv82TRUGYoPuXhYXVuMCKHkhLz44W6FijxW2e9n3T1hgyxcVq', FALSE, FALSE, TRUE,'twown.col@example.com', @three_col_id, 'User', 'Column', 'Two');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_9 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_9, 'three.col', '$2a$10$ImRXq4gFC9teBstOBdQrZeEwBkCAJ0S6.CwI9/9r7fxWKTZ30pgVC', FALSE, FALSE, TRUE,'three.col@example.com', @three_col_id, 'User', 'Column', 'Three');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_10 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_10, 'threewn.col', '$2a$10$LLYTJoK6MCBpeDBbmdt7tu1LNt7Eenqe1IpMlfem8xVjzynn.HpxW', FALSE, FALSE, TRUE,'threewn.col@example.com', @three_col_id, 'User', 'Column2', 'Three');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_11 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_11, 'four.col', '$2a$10$tZgWcaG2EJPLtseZ339n7uTu3GZn31h3iTr20orwgbbRAI15uoIFK', FALSE, FALSE, TRUE,'four.col@example.com', @three_col_id, 'User', 'Column', 'Four');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+set @user_id_12 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_12, 'fourwn.col', '$2a$10$4kPYhgowurWqXGVDigxOxOVj/M.rqLRwqbn0kT/OD4pISL6pDG/c2', FALSE, FALSE, TRUE,'fourwn.col@example.com', @three_col_id, 'User', 'Column2', 'Four');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+-- duplicate user id!!
+set @user_id_13 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @user_seq);
+insert into person (entity_id, username, password, expired, locked, enabled, email, default_page_layout_id, dtype, family_name, given_name)
+values (@user_id_13, 'http://rave2011.myopenid.com/', '$2a$10$dML97.rnOn4.iSlEEdju8OCB2NckuKw0Ki5yMVzzMmWQsWMvym3qC', FALSE, FALSE, TRUE,'rave2011_openid@example.org', @three_col_id, 'User', 'Openid', 'Rave');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @user_seq;
+
+--- end user data ---
+
+--- gadget data ---
+-- wikipedia widget
+set @wikipedia_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, description, author, widget_status, owner_id)
+values(@wikipedia_widget_id, 'Wikipedia','http://www.widget-dico.com/wikipedia/google/wikipedia.xml', 'OpenSocial', 'A Wikipedia Search and Go widget. Language choice.', 'WidgetMe', 'PUBLISHED', @user_id_2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- translate widget
+set @translate_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, description, author, widget_status, owner_id)
+values(@translate_widget_id, 'Translate Gadget', 'http://www.gstatic.com/ig/modules/dictionary/dictionary.xml','OpenSocial' , 'Google Translation gadget.', 'Google Taiwan', 'PUBLISHED', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- nytimes widget
+set @nyt_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, owner_id,featured)
+values(@nyt_widget_id, 'NYTimes.com - Top Stories', 'http://widgets.nytimes.com/packages/html/igoogle/topstories.xml', 'OpenSocial', 'PUBLISHED', @user_id_1,true );
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- google tabbed news widget
+set @tabnews_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, owner_id)
+values(@tabnews_widget_id, 'Google News Gadget', 'http://www.gstatic.com/ig/modules/tabnews/tabnews.xml', 'OpenSocial', 'PUBLISHED', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- hamster widget
+set @hamster_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, thumbnail_url, owner_id)
+values(@hamster_widget_id, 'Pet Hamster', 'http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamster.xml', 'OpenSocial', 'PUBLISHED', 'http://hosting.gmodules.com/ig/gadgets/file/112581010116074801021/hamsterThumb.png', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- another hamster widget
+set @another_hamster_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, description, author, widget_status, thumbnail_url, screenshot_url, owner_id)
+values(@another_hamster_widget_id, 'Herbie Hamster Virtual Pet', 'http://hosting.gmodules.com/ig/gadgets/file/109548057311228444554/hamster.xml', 'OpenSocial', 'A cute little hamster for you to feed and look after. Watch him follow your cursor around. Click on the more tab to treat him to a strawberry. Click him then put him on the wheel and watch him play! ***NEW: make Herbie hamster your very own!', 'Naj', 'PUBLISHED', 'http://sites.google.com/site/najartsist/pets-1/herbiet.png', 'http://sites.google.com/site/najartsist/herbie-hamster/herbie.png', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- slideshare widget
+set @gifts_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, owner_id)
+values(@gifts_widget_id, 'Gifts', 'http://opensocial-resources.googlecode.com/svn/samples/tutorial/tags/api-0.8/gifts_1_friends.xml', 'OpenSocial', 'PUBLISHED', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- demo widgets from rave-demos
+-- CTSS resource google map
+set @ctss_resources_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, description, author, widget_status, thumbnail_url, screenshot_url, owner_id)
+values(@ctss_resources_widget_id, 'List of CTSS Resources - Map View', 'http://localhost:8080/demogadgets/CTSSResourcesMapView.xml', 'OpenSocial', 'This is a gadget developed for Teragrid - OGCE project. Used Google gadgets API to retrieve the information from the Information Services REST Web Service and display the information using Google Maps API. This is a list of available CTSS resources and its details', 'Suresh Deivasigamani', 'PUBLISHED', 'http://img695.imageshack.us/img695/2726/ctssresourcesmapviewscr.png', 'http://img704.imageshack.us/img704/444/ctssresourcesmapview.png', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- Twitter Gadget
+set @twitter_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, description, author, widget_status, thumbnail_url, screenshot_url, owner_id)
+values(@twitter_widget_id, 'Twitter', 'http://localhost:8080/demogadgets/twitter.xml', 'OpenSocial', 'Fully functional, lightweight, AJAX-based twitter user interface with many configuration options including user specified auto-refresh rate, full timeline, pagination, and more.  Control display elements such as user thumbnails, date stamps, and post source.  Specify gadget size based on availble screen footprint, even incorporate into your Gmail account.  Insert symbols, dingbats and emoticons into your tweets using the TwitterGadget Symbols pulldown menu.', 'LOGIKA Corporation', 'PUBLISHED', 'http://www.twittergadget.com/images/thumbnail2.png', 'http://www.twittergadget.com/images/thumbnail2.png', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- Youtube Gadget
+set @youtube_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, description, author, widget_status, thumbnail_url, screenshot_url, owner_id)
+values(@youtube_widget_id, 'Youtube', 'http://localhost:8080/demogadgets/youtubesearch.xml', 'OpenSocial', 'A search module, which searches YouTube by tags like Politics News Life Music Family Photography Art Random Travel Personal Religion Movies Business Thoughts Media Humor Culture Poetry Christmas Writing Books Food Friends.', 'David Olsen', 'PUBLISHED', 'http://www.zytu.com/youtube/youtubesearchthumb.png', 'http://www.zytu.com/youtube/youtubesearchscreen.png', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- View information
+set @gadgetview_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, owner_id)
+values(@gadgetview_widget_id, 'Gadget View Type', 'http://localhost:8080/demogadgets/canvas-nav.xml', 'OpenSocial', 'PUBLISHED', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- View information
+set @user_prefs_demo_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, description, author, owner_id)
+values(@user_prefs_demo_widget_id, 'User Prefs Demo', 'http://localhost:8080/demogadgets/user_prefs_demo.xml', 'OpenSocial', 'PUBLISHED', 'An example gadget which demos some of the different capabilities of user preferences.', 'Anthony Carlucci', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- my activity
+set @my_activity_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, description, author, owner_id)
+values(@my_activity_widget_id, 'My Activity', 'http://localhost:8080/demogadgets/my_activity.xml', 'OpenSocial', 'PUBLISHED', 'Static widget of activities for demoing on the Person Profile page', 'Anthony Carlucci', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- schedule
+set @schedule_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, description, author, owner_id)
+values(@schedule_widget_id, 'Current Schedule', 'http://localhost:8080/demogadgets/schedule.xml', 'OpenSocial', 'PUBLISHED', 'Static widget of a schedule for demoing on the Person Profile page', 'Anthony Carlucci', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- favorite websites
+set @favorite_websites_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, description, author, owner_id)
+values(@favorite_websites_widget_id, 'Favorite Websites', 'http://localhost:8080/demogadgets/favorite_websites.xml', 'OpenSocial', 'PUBLISHED', 'Static widget of favorite websites for demoing on the Person Profile page', 'Anthony Carlucci', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- my groups
+set @my_groups_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, description, author, owner_id)
+values(@my_groups_widget_id, 'My Groups', 'http://localhost:8080/demogadgets/my_groups.xml', 'OpenSocial', 'PUBLISHED', 'Static widget of groups for demoing on the Person Profile page', 'Anthony Carlucci', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+-- work experience
+set @work_experience_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id, title, url, type, widget_status, description, author, owner_id)
+values(@work_experience_widget_id, 'Work Experience', 'http://localhost:8080/demogadgets/work_experience.xml', 'OpenSocial', 'PUBLISHED', 'Static widget of work experience for demoing on the Person Profile page', 'Anthony Carlucci', @user_id_1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+
+
+-- end widget data ----
+
+-- User layouts
+
+--- Layout for user_id_1 ---
+set @page_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_1_id, 'Main', @user_id_1, null, @two_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_1_id, @user_id_1, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data
+
+set @page_1_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_1, @page_1_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_1_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_2, @page_1_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_1_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_1_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @nyt_widget_id, @page_1_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_1_region_2, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_widget_rating = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_rating_seq);
+INSERT INTO widget_rating(entity_id, widget_id, user_id, score)
+values (@next_widget_rating, 1, 1, 0);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_rating_seq;
+
+set @next_widget_rating = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_rating_seq);
+INSERT INTO widget_rating(entity_id, widget_id, user_id, score)
+values (@next_widget_rating, 2, 1, 10);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_rating_seq;
+
+set @page_2_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_2_id, 'Social', @user_id_1, null, @two_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_2_id, @user_id_1, true, 2, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data
+
+set @page_2_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_2_region_1, @page_2_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_2_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_2_region_2, @page_2_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @nyt_widget_id, @page_2_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_2_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_2_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_2_region_2, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_widget_comment = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE Seq_name = @widget_comment_seq);
+INSERT INTO widget_comment(entity_id, widget_id, user_id, text)
+values (@next_widget_comment, 1, 1, 'test comment');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_comment_seq;
+
+set @next_widget_comment = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE Seq_name = @widget_comment_seq);
+INSERT INTO widget_comment(entity_id, widget_id, user_id, text)
+values (@next_widget_comment, 1, 1, 'another comment');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_comment_seq;
+
+-- person profile page for user 1
+set @person_profile_page_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@person_profile_page_id , 'Person Profile', @user_id_1, null, @person_profile_layout_id, 'PERSON_PROFILE');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @person_profile_page_id, @user_id_1, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @person_profile_page_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@person_profile_page_region_1, @person_profile_page_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @my_groups_widget_id, @person_profile_page_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @work_experience_widget_id, @person_profile_page_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+-- sub pages for profile page for user 1
+set @sub_page_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@sub_page_1_id , 'About', @user_id_1, @person_profile_page_id, @one_col_id, 'SUB_PAGE');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @sub_page_1_id, @user_id_1, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+set @sub_page_1_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@sub_page_1_region_1, @sub_page_1_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @favorite_websites_widget_id , @sub_page_1_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @schedule_widget_id, @sub_page_1_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @sub_page_2_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@sub_page_2_id , 'My Activity', @user_id_1, @person_profile_page_id, @one_col_id, 'SUB_PAGE');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @sub_page_2_id, @user_id_1, true, 2, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+set @sub_page_2_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@sub_page_2_region_1, @sub_page_2_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @my_activity_widget_id, @sub_page_2_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End canonical user_id_1 layout ---
+
+--- Layout for user_id_2 ---
+set @page_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_1_id, 'Main', @user_id_2, null, @two_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_1_id, @user_id_2, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_1_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_1, @page_1_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_1_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_2, @page_1_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_1_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_1_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @nyt_widget_id, @page_1_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_1_region_2, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End john.doe user_id_2 layout ---
+
+--- Layout for user_id_3 ---
+set @page_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_1_id, 'Main', @user_id_3, null, @two_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_1_id, @user_id_3, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_1_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_1, @page_1_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_1_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_2, @page_1_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_1_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_1_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_1_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_1_region_2, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End jane.doe user_id_3 layout ---
+
+--- Layout for user_id_4 ---
+set @page_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_1_id, 'Main', @user_id_4, null, @two_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_1_id, @user_id_4, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+--- End user_id_4 layout ---
+
+--- Layout for user_id_5 ---
+set @page_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_1_id, 'Main', @user_id_5, null, @two_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_1_id, @user_id_5, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+--- End user_id_5 layout ---
+
+
+
+--- Layout for user_id_6 ---
+set @page_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_1_id, 'Main', @user_id_6, null, @two_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_1_id, @user_id_6, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_1_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_1, @page_1_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_1_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_1_region_2, @page_1_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_1_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_1_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_1_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_1_region_2, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End user_id_6 layout ---
+
+--- Layout for user_id_7 ---
+set @page_7_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_7_id, 'Main', @user_id_7, null, @one_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_7_id, @user_id_7, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_7_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_7_region_1, @page_7_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_7_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_7_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End asgoyal.one user_id_7 layout ---
+
+--- Layout for user_id_8 ---
+set @page_8_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_8_id, 'Main', @user_id_8, null, @twown_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_8_id, @user_id_8, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_8_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_8_region_1, @page_8_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_8_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_8_region_2, @page_8_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_8_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_8_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_8_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_8_region_2, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End asgoyal.twown user_id_8 layout ---
+
+--- Layout for user_id_9 ---
+set @page_9_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_9_id, 'Main', @user_id_9, null, @three_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_9_id, @user_id_9, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_9_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_9_region_1, @page_9_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_9_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_9_region_2, @page_9_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_9_region_3 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_9_region_3, @page_9_id, 3);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_9_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_9_region_3, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_9_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_9_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End asgoyal.three user_id_9 layout ---
+
+--- Layout for user_id_10 ---
+set @page_10_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_10_id, 'Main', @user_id_10, null, @threewn_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_10_id, @user_id_10, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_10_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_10_region_1, @page_10_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_10_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_10_region_2, @page_10_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_10_region_3 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_10_region_3, @page_10_id, 3);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_10_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_10_region_3, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_10_region_1, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_10_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End asgoyal.threewn user_id_10 layout ---
+
+--- Layout for user_id_11 ---
+set @page_11_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_11_id, 'Main', @user_id_11, null, @four_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_11_id, @user_id_11, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_11_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_11_region_1, @page_11_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_11_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_11_region_2, @page_11_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_11_region_3 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_11_region_3, @page_11_id, 3);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_11_region_4 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_11_region_4, @page_11_id, 4);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_11_region_4, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_11_region_3, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_11_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_11_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+--- End asgoyal.four user_id_11 layout ---
+
+--- Layout for user_id_12 ---
+set @page_12_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_12_id, 'Main', @user_id_12, null, @fourwn_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_12_id, @user_id_12, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_12_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_12_region_1, @page_12_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_12_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_12_region_2, @page_12_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_12_region_3 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_12_region_3, @page_12_id, 3);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_12_region_4 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_12_region_4, @page_12_id, 4);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_12_region_4, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_12_region_3, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_12_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_12_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End asgoyal.fourwn user_id_12 layout ---
+
+--- Layout for user_id_13 ---
+set @page_13_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_seq);
+INSERT INTO page (entity_id, name, owner_id, parent_page_id, page_layout_id, page_type)
+values (@page_13_id, 'Main', @user_id_13, null, @fourwn_col_id, 'USER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_seq;
+
+--Set up page user data--
+set @page_user_id =(SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_user_seq);
+insert into page_user (entity_id, page_id, user_id, editor, render_sequence, page_status)
+values (@page_user_id, @page_13_id, @user_id_13, true, 1, 'OWNER');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_user_seq;
+--end page user data--
+
+set @page_13_region_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_13_region_1, @page_13_id, 1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_13_region_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_13_region_2, @page_13_id, 2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_13_region_3 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_13_region_3, @page_13_id, 3);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @page_13_region_4 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_seq);
+INSERT INTO region(entity_id, page_id, render_order)
+values (@page_13_region_4, @page_13_id, 4);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @hamster_widget_id, @page_13_region_4, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @tabnews_widget_id, @page_13_region_3, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @wikipedia_widget_id, @page_13_region_2, 0, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+
+set @next_region_widget = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @region_widget_seq);
+INSERT INTO region_widget(entity_id, widget_id, region_id, render_order, collapsed)
+values (@next_region_widget, @translate_widget_id, @page_13_region_1, 1, FALSE);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @region_widget_seq;
+--- End openid user_id_13 layout ---
+
+--- gadget data ---
+
+-- useless knowledge widget
+set @widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_seq);
+insert into widget (entity_id,title, url, type, widget_status)
+values(@widget_id,'Useless Knowledge', 'http://www.great-goofy-gadgets.com/humor/uselessknowledge/uselessknowledge.xml', 'OpenSocial', 'PREVIEW');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_seq;
+-- end widget data ----
+
+-- authorities
+set @next_authority_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @granted_authority_seq);
+insert into granted_authority (entity_id, authority, default_for_new_user)
+values (@next_authority_id, 'user', true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @granted_authority_seq;
+
+set @next_authority_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @granted_authority_seq);
+insert into granted_authority (entity_id, authority, default_for_new_user)
+values (@next_authority_id, 'manager', false);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @granted_authority_seq;
+
+set @next_authority_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @granted_authority_seq);
+insert into granted_authority (entity_id, authority, default_for_new_user)
+values (@next_authority_id, 'administrator', false);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @granted_authority_seq;
+
+-- end authorities
+
+-- portal preferences
+set @next_portal_preference_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @portal_preference_seq);
+INSERT INTO portal_preference (entity_id, preference_key)
+values (@next_portal_preference_id, 'color');
+INSERT INTO JPAPORTALPREFERENCE_VALUES
+values (@next_portal_preference_id, 'red');
+INSERT INTO JPAPORTALPREFERENCE_VALUES
+values (@next_portal_preference_id, 'yellow');
+INSERT INTO JPAPORTALPREFERENCE_VALUES
+values (@next_portal_preference_id, 'blue');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @portal_preference_seq;
+
+set @next_portal_preference_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @portal_preference_seq);
+INSERT INTO portal_preference (entity_id, preference_key)
+values (@next_portal_preference_id, 'title');
+INSERT INTO JPAPORTALPREFERENCE_VALUES
+values (@next_portal_preference_id, 'Rave');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @portal_preference_seq;
+-- end portal preferences
+
+set @tag_1_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @tag_seq);
+insert into tag (entity_id, keyword)
+values (@tag_1_id, 'news');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @tag_seq;
+
+set @tag_2_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @tag_seq);
+insert into tag (entity_id, keyword)
+values (@tag_2_id, 'wikipedia');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @tag_seq;
+
+set @tag_3_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @tag_seq);
+insert into tag (entity_id, keyword)
+values (@tag_3_id, 'misc');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @tag_seq;
+
+
+set @next_widget_tag_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_tag_seq);
+insert into widget_tag (entity_id, widget_id, tag_id)
+values (@next_widget_tag_id, 3,1);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_tag_seq;
+
+set @next_widget_tag_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @widget_tag_seq);
+insert into widget_tag (entity_id, widget_id, tag_id)
+values (@next_widget_tag_id, 1,2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @widget_tag_seq;
+
+-- category
+set @category_id1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @category_seq);
+insert into category (entity_id, text, created_user_id, created_date, last_modified_user_id, last_modified_date)
+values (@category_id1, 'Sample Category', @user_id_1, '2012-01-19', @user_id_2, '2012-01-22');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @category_seq;
+
+set @category_id2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @category_seq);
+insert into category (entity_id, text, created_user_id, created_date, last_modified_user_id, last_modified_date)
+values (@category_id2, 'AAA Category', @user_id_1, '2012-01-19', @user_id_2, '2012-01-19');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @category_seq;
+
+set @category_id3 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @category_seq);
+insert into category (entity_id, text, created_user_id, created_date, last_modified_user_id, last_modified_date)
+values (@category_id3, 'News Category', @user_id_1, '2012-01-19', @user_id_2, '2012-01-19');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @category_seq;
+
+set @category_id4 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @category_seq);
+insert into category (entity_id, text, created_user_id, created_date, last_modified_user_id, last_modified_date)
+values (@category_id4, 'Technology Category', @user_id_1, '2012-01-19', @user_id_2, '2012-01-19');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @category_seq;
+
+-- widget category
+insert into widget_category (widget_id, category_id)
+values (@wikipedia_widget_id, @category_id4);
+insert into widget_category (widget_id, category_id)
+values (@wikipedia_widget_id, @category_id2);
+
+----------------------------------------
+-- person profile parent page templates
+----------------------------------------
+-- page
+set @person_profile_page_template_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_seq);
+insert into page_template (entity_id, page_type, page_layout_id, name, description, parent_page_template_id, render_sequence, default_template)
+values (@person_profile_page_template_id, 'PERSON_PROFILE', @person_profile_layout_id, 'Person Profile', 'Template for person profile pages', null, 0, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_seq;
+
+-- regions
+set @person_profile_page_template_region_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_region_seq);
+insert into page_template_region (entity_id, render_sequence, page_template_id, locked)
+values (@person_profile_page_template_region_id, 0, @person_profile_page_template_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_region_seq;
+
+-- widgets
+set @next_person_profile_page_template_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_widget_seq);
+insert into page_template_widget (entity_id, page_template_region_id, render_sequence, widget_id, locked)
+values (@next_person_profile_page_template_widget_id, @person_profile_page_template_region_id, 0, @my_groups_widget_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_widget_seq;
+
+set @next_person_profile_page_template_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_widget_seq);
+insert into page_template_widget (entity_id, page_template_region_id, render_sequence, widget_id, locked)
+values (@next_person_profile_page_template_widget_id, @person_profile_page_template_region_id, 1, @work_experience_widget_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_widget_seq;
+
+------------------------------------------
+-- person profile about sub page templates
+------------------------------------------
+-- page
+set @person_profile_subpage1_template_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_seq);
+insert into page_template (entity_id, page_type, page_layout_id, name, description, parent_page_template_id, render_sequence, default_template)
+values (@person_profile_subpage1_template_id, 'SUB_PAGE', @one_col_id, 'About', 'Template for the About sub page for the person profile', @person_profile_page_template_id, 0, false);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_seq;
+
+-- regions
+set @person_profile_subpage1_template_region_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_region_seq);
+insert into page_template_region (entity_id, render_sequence, page_template_id, locked)
+values (@person_profile_subpage1_template_region_id, 0, @person_profile_subpage1_template_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_region_seq;
+
+-- widgets
+set @next_person_profile_subpage1_template_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_widget_seq);
+insert into page_template_widget (entity_id, page_template_region_id, render_sequence, widget_id, locked)
+values (@next_person_profile_subpage1_template_widget_id, @person_profile_subpage1_template_region_id, 0, @favorite_websites_widget_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_widget_seq;
+
+set @next_person_profile_subpage1_template_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_widget_seq);
+insert into page_template_widget (entity_id, page_template_region_id, render_sequence, widget_id, locked)
+values (@next_person_profile_subpage1_template_widget_id, @person_profile_subpage1_template_region_id, 1, @schedule_widget_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_widget_seq;
+
+--------------------------------------------------
+-- person profile my activities sub page templates
+--------------------------------------------------
+-- page
+set @person_profile_subpage2_template_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_seq);
+insert into page_template (entity_id, page_type, page_layout_id, name, description, parent_page_template_id, render_sequence, default_template)
+values (@person_profile_subpage2_template_id, 'SUB_PAGE', @one_col_id, 'My Activity', 'Template for the My Activity sub page for the person profile', @person_profile_page_template_id, 1, false);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_seq;
+
+-- regions
+set @person_profile_subpage2_template_region_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_region_seq);
+insert into page_template_region (entity_id, render_sequence, page_template_id, locked)
+values (@person_profile_subpage2_template_region_id, 0, @person_profile_subpage2_template_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_region_seq;
+
+-- widgets
+set @next_person_profile_subpage2_template_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_widget_seq);
+insert into page_template_widget (entity_id, page_template_region_id, render_sequence, widget_id, locked)
+values (@next_person_profile_subpage2_template_widget_id, @person_profile_subpage2_template_region_id, 0, @my_activity_widget_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_widget_seq;
+
+
+----------------------------------------
+-- user page template
+----------------------------------------
+-- page
+set @user_profile_page_template_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_seq);
+insert into page_template (entity_id, page_type, page_layout_id, name, description, parent_page_template_id, render_sequence, default_template)
+values (@user_profile_page_template_id, 'USER', @person_profile_layout_id, 'User Profile', 'User profile pages', null, 0, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_seq;
+
+-- region1
+set @user_profile_page_template_region_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_region_seq);
+insert into page_template_region (entity_id, render_sequence, page_template_id, locked)
+values (@user_profile_page_template_region_id, 0, @user_profile_page_template_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_region_seq;
+
+-- widgets
+set @next_user_profile_page_template_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_widget_seq);
+insert into page_template_widget (entity_id, page_template_region_id, render_sequence, widget_id, locked)
+values (@next_user_profile_page_template_widget_id, @user_profile_page_template_region_id, 0, @my_groups_widget_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_widget_seq;
+
+set @next_user_profile_page_template_widget_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @page_template_widget_seq);
+insert into page_template_widget (entity_id, page_template_region_id, render_sequence, widget_id, locked)
+values (@next_user_profile_page_template_widget_id, @user_profile_page_template_region_id, 1, @work_experience_widget_id, true);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @page_template_widget_seq; set @token_info_seq = 'token_info';
+
+
+set @token_info_id_1 = (SELECT seq_count FROM RAVE_SHINDIG_SEQUENCES WHERE seq_name = @token_info_seq);
+INSERT INTO oauth_token_info(entity_id, access_token, token_secret, session_handle, token_expire_millis, app_url, module_id, token_name, service_name, user_id)
+VALUES (@token_info_id_1, 'accessToken', 'tokenSecret', 'sessionHandle', 3600000, 'http://localhost:8080/samplecontainer/examples/oauth.xml', 'NOT_USED', 'tokenName', 'serviceName', 'john.doe');
+UPDATE RAVE_SHINDIG_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @token_info_seq;
+
+set @consumer_store_id_1 = (SELECT seq_count FROM RAVE_SHINDIG_SEQUENCES WHERE seq_name = @oauth_consumer_store_seq);
+INSERT INTO oauth_consumer_store(entity_id, gadget_uri, service_name, consumer_key, consumer_secret, key_type, key_name, callback_url)
+VALUES (@consumer_store_id_1, 'http://localhost:8080/samplecontainer/examples/oauth.xml', 'Google', 'gadgetConsumer', 'gadgetSecret', 'HMAC_SYMMETRIC', 'keyName', 'http://oauth.gmodules.com/gadgets/oauthcallback');
+UPDATE RAVE_SHINDIG_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @oauth_consumer_store_seq;
+
+set @application_data_id_1 = (SELECT seq_count FROM RAVE_SHINDIG_SEQUENCES WHERE seq_name = @application_data_seq);
+INSERT INTO application_data(entity_id, user_id, app_url, serialized_data, dtype)
+VALUES (@application_data_id_1, '12345', 'http://example.com/gadget.xml', '{"color":"blue","speed":"fast","state":"MA"}', 'JpaApplicationDataRepository$JpaSerializableApplicationData');
+UPDATE RAVE_SHINDIG_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @application_data_seq;
+
+set @next_person_association = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @person_association_seq);
+INSERT INTO person_association(entity_id, follower_id, followed_id)
+VALUES (@next_person_association, @user_id_1, @user_id_2);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @person_association_seq;
+
+set @next_person_association = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @person_association_seq);
+INSERT INTO person_association(entity_id, follower_id, followed_id)
+VALUES (@next_person_association, @user_id_1, @user_id_3);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @person_association_seq;
+
+set @next_person_association = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @person_association_seq);
+INSERT INTO person_association(entity_id, follower_id, followed_id)
+VALUES (@next_person_association, @user_id_2, @user_id_4);
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @person_association_seq;
+
+set @group_id_1 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @groups_seq);
+INSERT INTO groups(entity_id, title, description)
+VALUES (@group_id_1, 'Party', 'Party Group');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @groups_seq;
+
+set @group_id_2 = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @groups_seq);
+INSERT INTO groups(entity_id, title, description)
+VALUES (@group_id_2, 'Portal', 'Portal Group');
+UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @groups_seq;
+
+INSERT INTO group_members(group_id, person_id)
+VALUES (@group_id_1, @user_id_1);
+
+INSERT INTO group_members(group_id, person_id)
+VALUES (@group_id_1, @user_id_5);
diff --git a/rave-components/rave-web/pom.xml b/rave-components/rave-web/pom.xml
index a01c3e0..1118bca 100644
--- a/rave-components/rave-web/pom.xml
+++ b/rave-components/rave-web/pom.xml
@@ -53,6 +53,10 @@
             <artifactId>jcl-over-slf4j</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mrbean</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
         </dependency>
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java
index 5c91674..9c0c39e 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rest/WidgetApi.java
@@ -20,6 +20,10 @@
 package org.apache.rave.portal.web.api.rest;

 

 import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.TagImpl;

+import org.apache.rave.portal.model.impl.WidgetCommentImpl;

+import org.apache.rave.portal.model.impl.WidgetRatingImpl;

+import org.apache.rave.portal.model.impl.WidgetTagImpl;

 import org.apache.rave.portal.service.*;

 import org.slf4j.Logger;

 import org.slf4j.LoggerFactory;

@@ -66,7 +70,7 @@
     public void createWidgetComment(@PathVariable long widgetId,

                                     @RequestParam String text,

                                     HttpServletResponse response) {

-        WidgetComment widgetComment = new WidgetComment();

+        WidgetComment widgetComment = new WidgetCommentImpl();

         widgetComment.setWidgetId(widgetId);

         widgetComment.setUser(userService.getAuthenticatedUser());

         widgetComment.setText(text);

@@ -92,7 +96,7 @@
 

         WidgetComment widgetComment = widgetCommentService.getWidgetComment(widgetCommentId);

         if (widgetComment == null) {

-            widgetComment = new WidgetComment();

+            widgetComment = new WidgetCommentImpl();

             widgetComment.setWidgetId(widgetId);

             widgetComment.setUser(userService.getAuthenticatedUser());

             widgetComment.setCreatedDate(new Date());

@@ -120,7 +124,7 @@
                                    HttpServletResponse response) {

         logger.debug("DELETE WidgetRating received for /api/rest/widgets/{}", widgetId);

 

-        widgetRatingService.removeWidgetRating(widgetId, userService.getAuthenticatedUser().getEntityId());

+        widgetRatingService.removeWidgetRating(widgetId, userService.getAuthenticatedUser().getId());

 

         // send a 204 back for success since there is no content being returned

         response.setStatus(HttpStatus.NO_CONTENT.value());

@@ -132,9 +136,9 @@
                                 HttpServletResponse response) {

         logger.debug("POST WidgetRating received for /api/rest/widgets/{} score: {}", widgetId, score);

 

-        WidgetRating widgetRating = new WidgetRating();

+        WidgetRating widgetRating = new WidgetRatingImpl();

         widgetRating.setScore(score);

-        widgetRating.setUserId(userService.getAuthenticatedUser().getEntityId());

+        widgetRating.setUserId(userService.getAuthenticatedUser().getId());

         widgetRating.setWidgetId(widgetId);

         widgetRatingService.saveWidgetRating(widgetRating);

 

@@ -156,7 +160,7 @@
         if (tagText != null && !tagText.trim().isEmpty()) {

             WidgetTag existed = widgetTagService.getWidgetTagByWidgetIdAndKeyword(widgetId, tagText);

             if (existed == null) {

-                WidgetTag widgetTag = new WidgetTag();

+                WidgetTag widgetTag = new WidgetTagImpl();

                 widgetTag.setWidgetId(widgetId);

                 widgetTag.setUser(userService.getAuthenticatedUser());

                 widgetTag.setCreatedDate(new Date());

@@ -186,7 +190,7 @@
     private Tag getTag(String keyword) {

         Tag tag = tagService.getTagByKeyword(keyword);

         if (tag == null) {

-            tag = new Tag();

+            tag = new TagImpl();

             tag.setKeyword(keyword);

         }

         return tag;

diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java
index d3fb165..85376a5 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java
@@ -44,7 +44,7 @@
 

     /**

      * Adds a widget to the given page

-     * 

+     *

      * @param pageId

      *            the ID of the {@link org.apache.rave.portal.model.Page} to add

      *            the widget to

@@ -72,7 +72,7 @@
      * Moves a widget to a new location

      * <p/>

      * Moves can take place within a region, region to region, or between pages

-     * 

+     *

      * @param regionWidgetId

      *            the ID of the

      *            {@link org.apache.rave.portal.model.RegionWidget} to move

@@ -125,11 +125,11 @@
             }

         }.getResult();

     }

-    

+

 

     /**

      * Adds a new page

-     * 

+     *

      * @param pageName the new page name

      * @param pageLayoutCode the layout code for this new page

      * @return an {@link RpcOperation} containing the new page or any

@@ -144,7 +144,7 @@
              public Page execute() {

                  return pageService.addNewUserPage(pageName, pageLayoutCode);

              }

-        }.getResult();        

+        }.getResult();

     }

 

     @ResponseBody

@@ -170,10 +170,10 @@
             }

         }.getResult();

     }

-    

+

     /**

      * Moves a page to a new render position

-     * 

+     *

      * @param pageId the pageId to move

      * @param moveAfterPageId the pageId to move after in render order

      * @return an {@link RpcOperation} containing the updated page or any

@@ -181,7 +181,7 @@
      */

     @ResponseBody

     @RequestMapping(method = RequestMethod.POST, value = "{pageId}/move")

-    public RpcResult<Page> movePage(@PathVariable final long pageId, 

+    public RpcResult<Page> movePage(@PathVariable final long pageId,

                                     @RequestParam(required=false) final Long moveAfterPageId) {

         return new RpcOperation<Page>() {

             @Override

@@ -194,7 +194,7 @@
                 }

                 return page;

             }

-        }.getResult();        

+        }.getResult();

     }

 

     /**

diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ChangePasswordController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ChangePasswordController.java
index 3caed65..544497e 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ChangePasswordController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ChangePasswordController.java
@@ -19,8 +19,11 @@
 
 package org.apache.rave.portal.web.controller;
 
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.controller.util.ModelUtils;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.ChangePasswordValidator;
@@ -42,7 +45,7 @@
  * Only requests that have a valid (matched) forgotPasswordHash will be honored
  *
  * @version "$Id$"
- * @see org.apache.rave.portal.model.User#forgotPasswordHash
+ * @see org.apache.rave.portal.model.User#getForgotPasswordHash()
  */
 @Controller
 public class ChangePasswordController {
@@ -65,7 +68,7 @@
     @RequestMapping(value = {"/changepassword/{passwordHash:.*}"}, method = RequestMethod.GET)
     public String initialize(Model model, @PathVariable("passwordHash") String passwordHash) {
         log.debug("Requesting user for hash: {}", passwordHash);
-        User user = new User();
+        User user = new UserImpl();
         model.addAttribute(ModelKeys.USER, user);
         user.setForgotPasswordHash(passwordHash);
         return ViewNames.PASSWORD_CHANGE;
@@ -73,7 +76,7 @@
 
 
     @RequestMapping(value = {"/changepassword", "/changepassword/**"}, method = RequestMethod.POST)
-    public String update(@ModelAttribute User user, BindingResult results, Model model, RedirectAttributes redirectAttributes) {
+    public String update(@ModelAttribute UserForm user, BindingResult results, Model model, RedirectAttributes redirectAttributes) {
         log.debug("updating user password for hash {}", user.getForgotPasswordHash());
         model.addAttribute(ModelKeys.USER, user);
         passwordValidator.validate(user, results);
@@ -84,7 +87,7 @@
         }
         try {
             log.debug("Submitted passwords were valid");
-            userService.updatePassword(user);
+            userService.updatePassword(ModelUtils.convert(user));
             redirectAttributes.addFlashAttribute(ModelKeys.REDIRECT_MESSAGE, messagePasswordChanged);
             return ViewNames.REDIRECT_LOGIN ;
         } catch (Exception ex) {
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/MessageBundleController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/MessageBundleController.java
index a71b36b..e136a23 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/MessageBundleController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/MessageBundleController.java
@@ -26,6 +26,7 @@
 import org.springframework.stereotype.Controller;

 import org.springframework.web.bind.annotation.RequestMapping;

 import org.springframework.web.bind.annotation.RequestMethod;

+import org.springframework.web.bind.annotation.ResponseBody;

 import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

 

 import javax.servlet.http.HttpServletRequest;

@@ -68,6 +69,7 @@
      * @param request  The incoming HttpServletRequest

      * @return the JavaScript content to load from the client

      */

+    @ResponseBody

     @RequestMapping(value = {"/rave_client_messages.js"}, method = RequestMethod.GET)

     public ResponseEntity<String> getClientMessages(HttpServletRequest request) {

         return new ResponseEntity<String>(getClientMessagesJSForLocale(acceptHeaderLocaleResolver.resolveLocale(request)), clientMessagesResponseHeaders, HttpStatus.OK);

diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/NewAccountController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/NewAccountController.java
index 1852c32..37cbeb5 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/NewAccountController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/NewAccountController.java
@@ -19,11 +19,11 @@
 
 package org.apache.rave.portal.web.controller;
 
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.CaptchaService;
 import org.apache.rave.portal.service.NewAccountService;
+import org.apache.rave.portal.web.controller.util.ModelUtils;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.NewAccountValidator;
@@ -40,6 +40,8 @@
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import javax.servlet.http.HttpServletRequest;
+
 @Controller
 public class NewAccountController {
     private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -63,11 +65,11 @@
     public void setUpForm(ModelMap model, HttpServletRequest request) {
         logger.debug("Initializing form");
         model.addAttribute(ModelKeys.CAPTCHA_HTML, captchaService.createHtml(request));
-        model.addAttribute(ModelKeys.NEW_USER, new User());
+        model.addAttribute(ModelKeys.NEW_USER, new UserImpl());
     }
 
     @RequestMapping(value = {"/newaccount", "/newaccount/*"}, method = RequestMethod.POST)
-    public String create(@ModelAttribute(value = "newUser") User newUser, BindingResult results, Model model, HttpServletRequest request,  RedirectAttributes redirectAttributes) {
+    public String create(@ModelAttribute(value = "newUser") UserForm newUser, BindingResult results, Model model, HttpServletRequest request,  RedirectAttributes redirectAttributes) {
         logger.debug("Creating a new user account");
         model.addAttribute(ModelKeys.NEW_USER, newUser);
 
@@ -83,7 +85,7 @@
             logger.debug("newaccount.jsp: passed form validation");
 
             if (captchaService.isValid(request)) {
-                newAccountService.createNewAccount(newUser);
+                newAccountService.createNewAccount(ModelUtils.convert(newUser));
                 redirectAttributes.addFlashAttribute(ModelKeys.REDIRECT_MESSAGE, messageSuccess);
                 return ViewNames.REDIRECT_LOGIN;
             } else {
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java
index 34b9a07..3fd8280 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/PageController.java
@@ -18,17 +18,11 @@
  */
 package org.apache.rave.portal.web.controller;
 
-import org.apache.rave.portal.model.Page;
-import org.apache.rave.portal.model.PageInvitationStatus;
-import org.apache.rave.portal.model.PageLayout;
-import org.apache.rave.portal.model.PageUser;
-import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.*;
 import org.apache.rave.portal.service.PageLayoutService;
 import org.apache.rave.portal.service.PageService;
 import org.apache.rave.portal.service.UserService;
 import org.apache.rave.portal.web.controller.util.ControllerUtils;
-import org.apache.rave.portal.web.model.NavigationItem;
-import org.apache.rave.portal.web.model.NavigationMenu;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.slf4j.Logger;
@@ -84,10 +78,10 @@
         List<PageLayout> pageLayouts = pageLayoutService.getAllUserSelectable();
         addAttributesToModel(model, page, currentPageUser, pages, pageLayouts);
         String view = ControllerUtils.getDeviceAppropriateView(request, ViewNames.getPageView(page.getPageLayout().getCode()), ViewNames.MOBILE_HOME);
-        ControllerUtils.addNavItemsToModel(view, model, page.getEntityId(), userService.getAuthenticatedUser(), currentPageUser.isEditor());
+        ControllerUtils.addNavItemsToModel(view, model, page.getId(), userService.getAuthenticatedUser(), currentPageUser.isEditor());
         return view;
     }
-    
+
     @RequestMapping(value = "/page/view/{pageId}", method = RequestMethod.GET)
     public String view(@PathVariable Long pageId, Model model, HttpServletRequest request) {
         try {
@@ -103,7 +97,7 @@
             List<PageLayout> pageLayouts = pageLayoutService.getAllUserSelectable();
             addAttributesToModel(model, page, currentPageUser, pages, pageLayouts);
             String view = ControllerUtils.getDeviceAppropriateView(request, ViewNames.getPageView(page.getPageLayout().getCode()), ViewNames.MOBILE_HOME);
-            ControllerUtils.addNavItemsToModel(view, model, page.getEntityId(), thisUser, currentPageUser.isEditor());
+            ControllerUtils.addNavItemsToModel(view, model, page.getId(), thisUser, currentPageUser.isEditor());
             return view;
         } catch (Exception e) {
             logger.info("unable to get page - possibly because a shared page was revoked by its owner");
@@ -111,16 +105,16 @@
         // Page could not be found or a shared page was removed, in which case return to default view
         return viewDefault(model, request);
     }
-    
+
     private List<Page> getAllPagesForAuthenticatedUser() {
         User user = userService.getAuthenticatedUser();
-        long userId = user.getEntityId();
+        long userId = user.getId();
         List<Page> pages = pageService.getAllUserPages(userId);
         // we add pages to this list which the corresponding pageUser object is not set to "refused"
         List<Page> viewablePages = new ArrayList<Page>();
         for(Page page : pages){
             for(PageUser pageUser : page.getMembers()){
-                if(pageUser.getUser().equals(user) && !pageUser.getPageStatus().equals(PageInvitationStatus.REFUSED)){
+                if(pageUser != null && pageUser.getUser().equals(user) && !pageUser.getPageStatus().equals(PageInvitationStatus.REFUSED)){
                     viewablePages.add(page);
                 }
             }
@@ -134,7 +128,7 @@
         }
         return viewablePages;
     }
-    
+
     private void addAttributesToModel(Model model, Page page, PageUser pageUser, List<Page> pages, List<PageLayout> pageLayouts) {
         model.addAttribute(ModelKeys.PAGE, page);
         model.addAttribute(ModelKeys.PAGES, pages);
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ProfileController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ProfileController.java
index 0ed9a2b..c1b786f 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ProfileController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ProfileController.java
@@ -25,12 +25,12 @@
 import org.apache.rave.portal.service.UserService;
 import org.apache.rave.portal.web.controller.util.ControllerUtils;
 import org.apache.rave.portal.web.model.NavigationMenu;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.ui.ModelMap;
@@ -63,7 +63,7 @@
 	public String viewProfile(@PathVariable String username, ModelMap model, @RequestParam(required = false) Long referringPageId) {
 		logger.debug("Viewing person profile for: " + username);
 		User user = userService.getUserByUsername(username);
-        Page personProfilePage = pageService.getPersonProfilePage(user.getEntityId());
+        Page personProfilePage = pageService.getPersonProfilePage(user.getId());
         addAttributesToModel(model, user, referringPageId);
         model.addAttribute(ModelKeys.PAGE, personProfilePage);
 		String view =  ViewNames.getPersonPageView(personProfilePage.getPageLayout().getCode());
@@ -82,7 +82,7 @@
     @RequestMapping(method = RequestMethod.POST)
     public String updateProfile(ModelMap model,
                                 @RequestParam(required = false) Long referringPageId,
-                                @ModelAttribute("updatedUser") User updatedUser) {
+                                @ModelAttribute("updatedUser") UserForm updatedUser) {
         logger.info("Updating " + updatedUser.getUsername() + " profile information");
 
         User user = userService.getAuthenticatedUser();
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ReminderController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ReminderController.java
index b298e54..7c81181 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ReminderController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/ReminderController.java
@@ -19,11 +19,12 @@
 
 package org.apache.rave.portal.web.controller;
 
-import javax.servlet.http.HttpServletRequest;
-
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.CaptchaService;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.controller.util.ModelUtils;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.NewPasswordValidator;
@@ -39,6 +40,8 @@
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * Handles password ans username reminder requests
  *
@@ -65,7 +68,7 @@
     @RequestMapping(value = {"/retrieveusername", "/newpassword"})
     public void initialize(ModelMap model, HttpServletRequest request) {
         model.addAttribute(ModelKeys.CAPTCHA_HTML, captchaService.createHtml(request));
-        model.addAttribute(ModelKeys.USER, new User());
+        model.addAttribute(ModelKeys.USER, new UserImpl());
     }
 
 
@@ -73,9 +76,10 @@
      * Processes username requests
      */
     @RequestMapping(value = {"/retrieveusername"}, method = RequestMethod.POST)
-    public String requestUsername(@ModelAttribute User user, BindingResult results, Model model,
+    public String requestUsername(@ModelAttribute UserForm userForm, BindingResult results, Model model,
                                   HttpServletRequest request, RedirectAttributes redirectAttributes) {
         log.debug("Requesting username reminder");
+        User user = ModelUtils.convert(userForm);
         if (!validateEmail(user, results, model, request)) {
             return captchaRequest(model, request, ViewNames.USERNAME_REQUEST);
         }
@@ -97,9 +101,10 @@
      * Processes new password requests
      */
     @RequestMapping(value = {"/newpassword"}, method = RequestMethod.POST)
-    public String requestPassword(@ModelAttribute User user, BindingResult results, Model model,
+    public String requestPassword(@ModelAttribute UserForm userForm, BindingResult results, Model model,
                                   HttpServletRequest request, RedirectAttributes redirectAttributes) {
         log.debug("Requesting password reminder");
+        User user = ModelUtils.convert(userForm);
         if (!validateEmail(user, results, model, request)) {
             return captchaRequest(model, request, ViewNames.NEW_PASSWORD_REQUEST);
         }
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/UserProfileController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/UserProfileController.java
index 9cbade8..a9c2ddd 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/UserProfileController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/UserProfileController.java
@@ -21,6 +21,8 @@
 
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.controller.util.ModelUtils;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.UserProfileValidator;
@@ -66,7 +68,7 @@
     }
 
     @RequestMapping(value = {"/updateUserProfile", "/updateUserProfile/*"}, method = RequestMethod.POST)
-    public String create(@ModelAttribute User user, BindingResult results, Model model, @RequestParam String username, @RequestParam String password, RedirectAttributes redirectAttributes) {
+    public String create(@ModelAttribute UserForm user, BindingResult results, Model model, @RequestParam String username, @RequestParam String password, RedirectAttributes redirectAttributes) {
         logger.debug("Updating user profile.");
         model.addAttribute(ModelKeys.USER_PROFILE, user);
 
@@ -79,7 +81,7 @@
         //Now attempt to update the account.
         try {
             logger.debug("userprofile: passed form validation");
-            userService.updateUserProfile(user);
+            userService.updateUserProfile(ModelUtils.convert(user));
             redirectAttributes.addFlashAttribute(ModelKeys.REDIRECT_MESSAGE, profileUpdatedMessage);
             return ViewNames.REDIRECT_LOGIN;
         }
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java
index 2374e4e..0fcbb71 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/WidgetStoreController.java
@@ -20,10 +20,9 @@
 package org.apache.rave.portal.web.controller;
 
 import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.service.*;
 import org.apache.rave.portal.web.controller.util.ControllerUtils;
-import org.apache.rave.portal.web.model.NavigationItem;
-import org.apache.rave.portal.web.model.NavigationMenu;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.PortalPreferenceKeys;
 import org.apache.rave.portal.web.util.ViewNames;
@@ -91,7 +90,7 @@
         User user = userService.getAuthenticatedUser();
         widgetStoreModelHelper(model, referringPageId, user, view);
         model.addAttribute(ModelKeys.WIDGETS,
-                widgetService.getWidgetsByOwner(user.getEntityId(), offset, getPageSize()));
+                widgetService.getWidgetsByOwner(user.getId(), offset, getPageSize()));
         return view;
     }
 
@@ -112,7 +111,7 @@
         final User user = userService.getAuthenticatedUser();
         widgetStoreModelHelper(model, referringPageId, user, view);
         model.addAttribute(ModelKeys.WIDGET, widgetService.getWidget(widgetId));
-        model.addAttribute(ModelKeys.WIDGET_STATISTICS, widgetService.getWidgetStatistics(widgetId, user.getEntityId()));
+        model.addAttribute(ModelKeys.WIDGET_STATISTICS, widgetService.getWidgetStatistics(widgetId, user.getId()));
         model.addAttribute(ModelKeys.USER_PROFILE, user);
         return view;
     }
@@ -196,7 +195,7 @@
      */
     @RequestMapping(method = RequestMethod.GET, value = "widget/add")
     public String viewAddWidgetForm(Model model, @RequestParam long referringPageId) {
-        final Widget widget = new Widget();
+        final Widget widget = new WidgetImpl();
         final String view = ViewNames.ADD_WIDGET_FORM;
         model.addAttribute(ModelKeys.WIDGET, widget);
         model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
@@ -208,7 +207,7 @@
      * Validates the form input, if valid, tries to store the Widget data
      *
      * @param widget
-     *            {@link Widget} as submitted by the user
+     *            {@link org.apache.rave.portal.model.Widget} as submitted by the user
      * @param results
      *            {@link BindingResult}
      * @param model
@@ -218,7 +217,7 @@
      * @return if successful the view name of the widget, otherwise the form
      */
     @RequestMapping(method = RequestMethod.POST, value = "widget/add")
-    public String viewAddWidgetResult(@ModelAttribute Widget widget, BindingResult results, Model model,
+    public String viewAddWidgetResult(@ModelAttribute WidgetImpl widget, BindingResult results, Model model,
             @RequestParam long referringPageId) {
         User user = userService.getAuthenticatedUser();
         widgetValidator.validate(widget, results);
@@ -233,7 +232,7 @@
         widget.setOwner(user);
 
         final Widget storedWidget = widgetService.registerNewWidget(widget);
-        return "redirect:/app/store/widget/" + storedWidget.getEntityId() + "?referringPageId=" + referringPageId;
+        return "redirect:/app/store/widget/" + storedWidget.getId() + "?referringPageId=" + referringPageId;
     }
 
     /**
@@ -248,7 +247,7 @@
      */
     private void widgetStoreModelHelper(Model model, long referringPageId, User user, String view) {
         model.addAttribute(ModelKeys.REFERRING_PAGE_ID, referringPageId);
-        model.addAttribute(ModelKeys.WIDGETS_STATISTICS, widgetService.getAllWidgetStatistics(user.getEntityId()));
+        model.addAttribute(ModelKeys.WIDGETS_STATISTICS, widgetService.getAllWidgetStatistics(user.getId()));
         model.addAttribute(ModelKeys.TAGS, tagService.getAllTags());
         model.addAttribute(ModelKeys.CATEGORIES, categoryService.getAll());
         ControllerUtils.addNavItemsToModel(view, model, referringPageId, user);
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/CategoryController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/CategoryController.java
index cb416d7..237b2c9 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/CategoryController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/CategoryController.java
@@ -17,6 +17,7 @@
 

 import org.apache.rave.portal.model.Category;

 import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.impl.CategoryImpl;

 import org.apache.rave.portal.service.CategoryService;

 import org.apache.rave.portal.service.UserService;

 import org.apache.rave.portal.web.util.ModelKeys;

@@ -24,18 +25,12 @@
 import org.springframework.beans.factory.annotation.Autowired;

 import org.springframework.stereotype.Controller;

 import org.springframework.ui.Model;

-import org.springframework.web.bind.annotation.ModelAttribute;

-import org.springframework.web.bind.annotation.RequestMapping;

-import org.springframework.web.bind.annotation.RequestMethod;

-import org.springframework.web.bind.annotation.RequestParam;

-import org.springframework.web.bind.annotation.SessionAttributes;

+import org.springframework.web.bind.annotation.*;

 import org.springframework.web.bind.support.SessionStatus;

 

 import java.util.List;

 

-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.addNavigationMenusToModel;

-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.checkTokens;

-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.isCreateDeleteOrUpdate;

+import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.*;

 

 @Controller

 @SessionAttributes({ModelKeys.CATEGORY, ModelKeys.TOKENCHECK})

@@ -57,7 +52,7 @@
 

         model.addAttribute("categories", categories);

         // put category object in the model to allow creating categories from view

-        model.addAttribute(ModelKeys.CATEGORY, new Category());

+        model.addAttribute(ModelKeys.CATEGORY, new CategoryImpl());

         // add tokencheck attribute for creating new category

         model.addAttribute(ModelKeys.TOKENCHECK, AdminControllerUtil.generateSessionToken());

 

@@ -69,7 +64,7 @@
     }

 

     @RequestMapping(value = {"/admin/category/create"}, method = RequestMethod.POST)

-    public String createCategory(@ModelAttribute Category category,

+    public String createCategory(@ModelAttribute CategoryImpl category,

                                  @ModelAttribute(ModelKeys.TOKENCHECK) String sessionToken,

                                  @RequestParam String token,

                                  Model model,

@@ -97,7 +92,7 @@
         User currentUser = userService.getAuthenticatedUser();

         boolean isValidRequest = validateRequest(category, currentUser);

         if (isValidRequest) {

-            categoryService.update(category.getEntityId(), category.getText(), currentUser);

+            categoryService.update(category.getId(), category.getText(), currentUser);

         } else {

             addNavigationMenusToModel(SELECTED_ITEM, model);

             return ViewNames.ADMIN_CATEGORY_DETAIL;

@@ -147,7 +142,7 @@
     }

 

     private boolean validateRequest(Category category, User modifier){

-        return (validateRequest(category.getText(),modifier) && (categoryService.get(category.getEntityId()) != null));

+        return (validateRequest(category.getText(),modifier) && (categoryService.get(category.getId()) != null));

     }

 

     public void setUserService(UserService userService) {

diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/UserController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/UserController.java
index 64e65be..ecff4cf 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/UserController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/UserController.java
@@ -19,21 +19,15 @@
 
 package org.apache.rave.portal.web.controller.admin;
 
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.DEFAULT_PAGE_SIZE;
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.addNavigationMenusToModel;
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.checkTokens;
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.isDeleteOrUpdate;
-
-import java.beans.PropertyEditorSupport;
-
-import org.apache.rave.portal.model.Authority;
-import org.apache.rave.portal.model.PortalPreference;
-import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.service.AuthorityService;
 import org.apache.rave.portal.service.NewAccountService;
 import org.apache.rave.portal.service.PortalPreferenceService;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.controller.util.ModelUtils;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.PortalPreferenceKeys;
 import org.apache.rave.portal.web.util.ViewNames;
@@ -49,16 +43,14 @@
 import org.springframework.ui.ModelMap;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.support.SessionStatus;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import java.beans.PropertyEditorSupport;
+
+import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.*;
+
 /**
  * Admin controller to manipulate User data
  */
@@ -129,7 +121,7 @@
     @RequestMapping(value = "/admin/userdetail/{userid}", method = RequestMethod.GET)
     public String viewUserDetail(@PathVariable("userid") Long userid, Model model) {
         addNavigationMenusToModel(SELECTED_ITEM, model);
-        model.addAttribute(userService.getUserById(userid));
+        model.addAttribute(ModelKeys.USER, userService.getUserById(userid));
         model.addAttribute(ModelKeys.TOKENCHECK, AdminControllerUtil.generateSessionToken());
         return ViewNames.ADMIN_USERDETAIL;
     }
@@ -166,7 +158,7 @@
             modelMap.addAttribute("missingConfirm", true);
             return ViewNames.ADMIN_USERDETAIL;
         }
-        userService.deleteUser(user.getEntityId());
+        userService.deleteUser(user.getId());
         modelMap.clear();
         status.setComplete();
         return "redirect:/app/admin/users?action=delete";
@@ -176,13 +168,13 @@
     public String setUpForm(ModelMap model) {
         logger.debug("Initializing new account form");
         AdminControllerUtil.addNavigationMenusToModel(SELECTED_ITEM, (Model) model);
-        model.addAttribute(ModelKeys.NEW_USER, new User());
+        model.addAttribute(ModelKeys.NEW_USER, new UserImpl());
         return ViewNames.ADMIN_NEW_ACCOUNT;
 
     }
 
     @RequestMapping(value = {"/admin/newaccount", "/admin/newaccount/*"}, method = RequestMethod.POST)
-    public String create(@ModelAttribute(value = "newUser") User newUser, BindingResult results, Model model,
+    public String create(@ModelAttribute(value = "newUser") UserForm newUser, BindingResult results, Model model,
                          RedirectAttributes redirectAttributes) {
         logger.debug("Creating a new user account");
         model.addAttribute(ModelKeys.NEW_USER, newUser);
@@ -194,7 +186,7 @@
         }
         try {
             logger.debug("newaccount.jsp: passed form validation");
-            newAccountService.createNewAccount(newUser);
+            newAccountService.createNewAccount(ModelUtils.convert(newUser));
             redirectAttributes.addFlashAttribute(ModelKeys.REDIRECT_MESSAGE, messageSuccess);
             return "redirect:/app/admin/users";
         } catch (org.springframework.dao.IncorrectResultSizeDataAccessException ex) {
@@ -254,7 +246,7 @@
 
 
     /**
-     * Mapping between the submitted form value and an {@link Authority}
+     * Mapping between the submitted form value and an {@link org.apache.rave.portal.model.Authority}
      */
     private class AuthorityEditor extends PropertyEditorSupport {
 
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/WidgetController.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/WidgetController.java
index 1fe92b3..d032c03 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/WidgetController.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/admin/WidgetController.java
@@ -38,23 +38,11 @@
 import org.springframework.ui.ModelMap;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.support.SessionStatus;
 
-import java.beans.PropertyEditorSupport;
-import java.util.ArrayList;
-
 import static org.apache.rave.portal.model.WidgetStatus.values;
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.DEFAULT_PAGE_SIZE;
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.addNavigationMenusToModel;
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.checkTokens;
-import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.isDeleteOrUpdate;
+import static org.apache.rave.portal.web.controller.admin.AdminControllerUtil.*;
 
 /**
  * Admin controller to manipulate Widget data
@@ -120,7 +108,7 @@
     @RequestMapping(value = "/admin/widgetdetail/{widgetid}", method = RequestMethod.GET)
     public String viewWidgetDetail(@PathVariable("widgetid") Long widgetid, Model model) {
         addNavigationMenusToModel(SELECTED_ITEM, model);
-        model.addAttribute(widgetService.getWidget(widgetid));
+        model.addAttribute(ModelKeys.WIDGET, widgetService.getWidget(widgetid));
         model.addAttribute(ModelKeys.TOKENCHECK, AdminControllerUtil.generateSessionToken());
         model.addAttribute(ModelKeys.CATEGORIES, categoryService.getAll());
 
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/CategoryEditor.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/CategoryEditor.java
index 7adb3f6..9988b9e 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/CategoryEditor.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/CategoryEditor.java
@@ -35,7 +35,7 @@
     public CategoryEditor(CategoryService categoryService) {

         this.categoryService = categoryService;

     }

-    

+

     @Override

     public void setAsText(String text) throws IllegalArgumentException {

         setValue(categoryService.get(Long.parseLong(text)));

@@ -44,6 +44,6 @@
     @Override

     public String getAsText() {

         Category category = (Category)getValue();

-        return (category == null) ? null : category.getEntityId().toString();

+        return (category == null) ? null : category.getId().toString();

     }

 }
\ No newline at end of file
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ModelUtils.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ModelUtils.java
new file mode 100644
index 0000000..909d783
--- /dev/null
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/controller/util/ModelUtils.java
@@ -0,0 +1,35 @@
+package org.apache.rave.portal.web.controller.util;
+
+import org.apache.rave.portal.model.Authority;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.apache.rave.portal.web.model.UserForm;
+import org.apache.rave.util.CollectionUtils;
+
+/**
+ */
+public class ModelUtils {
+
+    private ModelUtils() {}
+
+
+    public static User convert(UserForm form) {
+        User newUser = new UserImpl(form.getId(),  form.getUsername());
+        newUser.setAuthorities(CollectionUtils.<Authority>toBaseTypedCollection(form.getAuthorities()));
+        newUser.setPassword(form.getPassword());
+        newUser.setConfirmPassword(form.getConfirmPassword());
+        newUser.setForgotPasswordHash(form.getForgotPasswordHash());
+        newUser.setDefaultPageLayoutCode(form.getDefaultPageLayoutCode());
+        newUser.setStatus(form.getStatus());
+        newUser.setAboutMe(form.getAboutMe());
+        newUser.setGivenName(form.getGivenName());
+        newUser.setFamilyName(form.getFamilyName());
+        newUser.setDisplayName(form.getDisplayName());
+        newUser.setEmail(form.getEmail());
+        newUser.setOpenId(form.getOpenId());
+        newUser.setEnabled(form.isEnabled());
+        newUser.setExpired(form.isExpired());
+        newUser.setLocked(form.isLocked());
+        return newUser;
+    }
+}
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/MaterializedBeanObjectMapperFactory.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/MaterializedBeanObjectMapperFactory.java
new file mode 100644
index 0000000..6462e4c
--- /dev/null
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/MaterializedBeanObjectMapperFactory.java
@@ -0,0 +1,27 @@
+package org.apache.rave.portal.web.model;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.mrbean.MrBeanModule;
+import org.springframework.beans.factory.FactoryBean;
+
+/**
+ * Configures the Jackson ObjectMapper to materialize interfaces
+ */
+public class MaterializedBeanObjectMapperFactory implements FactoryBean<ObjectMapper> {
+    @Override
+    public ObjectMapper getObject() throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new MrBeanModule());
+        return mapper;
+    }
+
+    @Override
+    public Class<?> getObjectType() {
+        return ObjectMapper.class;
+    }
+
+    @Override
+    public boolean isSingleton() {
+        return false;
+    }
+}
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java
index e5fab3b..b9948aa 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/PortalPreferenceForm.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.web.model;
 
 import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.impl.PortalPreferenceImpl;
 
 import java.util.Map;
 
@@ -45,13 +46,13 @@
 
     private void populateMissingPreferences() {
         if (getPageSize() == null) {
-            preferenceMap.put(PAGE_SIZE, new PortalPreference(PAGE_SIZE, DEFAULT_PAGE_SIZE));
+            preferenceMap.put(PAGE_SIZE, new PortalPreferenceImpl(PAGE_SIZE, DEFAULT_PAGE_SIZE));
         }
         if (getTitleSuffix() == null) {
-            preferenceMap.put(TITLE_SUFFIX, new PortalPreference(TITLE_SUFFIX, DEFAULT_TITLE_SUFFIX));
+            preferenceMap.put(TITLE_SUFFIX, new PortalPreferenceImpl(TITLE_SUFFIX, DEFAULT_TITLE_SUFFIX));
         }
         if (getJavaScriptDebugMode() == null) {
-            preferenceMap.put(JAVASCRIPT_DEBUG_MODE, new PortalPreference(JAVASCRIPT_DEBUG_MODE, DEFAULT_JAVASCRIPT_DEBUG_MODE));
+            preferenceMap.put(JAVASCRIPT_DEBUG_MODE, new PortalPreferenceImpl(JAVASCRIPT_DEBUG_MODE, DEFAULT_JAVASCRIPT_DEBUG_MODE));
         }
     }
 
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/UserForm.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/UserForm.java
new file mode 100644
index 0000000..f4fed45
--- /dev/null
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/model/UserForm.java
@@ -0,0 +1,243 @@
+package org.apache.rave.portal.web.model;
+
+import org.apache.rave.portal.model.impl.AuthorityImpl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Form backing object similar to User with concrete object references
+ */
+public class UserForm {
+
+    private Long id;
+    private Collection<AuthorityImpl> authorities;
+    private String password;
+    private String username;
+    private String confirmPassword;
+    private String forgotPasswordHash;
+    private String email;
+    private String openId;
+    private String defaultPageLayoutCode;
+    private String givenName;
+    private String familyName;
+    private String displayName;
+    private String status;
+    private String aboutMe;
+    private boolean locked;
+    private boolean credsExpired;
+    private boolean expired;
+    private boolean enabled;
+
+    public UserForm(Long userid, String username) {
+        this();
+        this.id = userid;
+        this.username = username;
+    }
+
+    public UserForm() {
+        this.authorities = new ArrayList<AuthorityImpl>();
+    }
+
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Collection<AuthorityImpl> getAuthorities() {
+        return authorities;
+    }
+
+    public void setAuthorities(Collection<AuthorityImpl> authorities) {
+        this.authorities = authorities;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getConfirmPassword() {
+        return confirmPassword;
+    }
+
+    public void setConfirmPassword(String confirmPassword) {
+        this.confirmPassword = confirmPassword;
+    }
+
+    public String getForgotPasswordHash() {
+        return forgotPasswordHash;
+    }
+
+    public void setForgotPasswordHash(String forgotPasswordHash) {
+        this.forgotPasswordHash = forgotPasswordHash;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getOpenId() {
+        return openId;
+    }
+
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
+    public String getDefaultPageLayoutCode() {
+        return defaultPageLayoutCode;
+    }
+
+    public void setDefaultPageLayoutCode(String defaultPageLayoutCode) {
+        this.defaultPageLayoutCode = defaultPageLayoutCode;
+    }
+
+    public String getGivenName() {
+        return givenName;
+    }
+
+    public void setGivenName(String givenName) {
+        this.givenName = givenName;
+    }
+
+    public String getFamilyName() {
+        return familyName;
+    }
+
+    public void setFamilyName(String familyName) {
+        this.familyName = familyName;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public void setDisplayName(String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getAboutMe() {
+        return aboutMe;
+    }
+
+    public void setAboutMe(String aboutMe) {
+        this.aboutMe = aboutMe;
+    }
+
+    public boolean isLocked() {
+        return locked;
+    }
+
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    public boolean isCredsExpired() {
+        return credsExpired;
+    }
+
+    public void setCredsExpired(boolean credsExpired) {
+        this.credsExpired = credsExpired;
+    }
+
+    public boolean isExpired() {
+        return expired;
+    }
+
+    public void setExpired(boolean expired) {
+        this.expired = expired;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof UserForm)) return false;
+
+        UserForm userForm = (UserForm) o;
+
+        if (credsExpired != userForm.credsExpired) return false;
+        if (enabled != userForm.enabled) return false;
+        if (expired != userForm.expired) return false;
+        if (locked != userForm.locked) return false;
+        if (aboutMe != null ? !aboutMe.equals(userForm.aboutMe) : userForm.aboutMe != null) return false;
+        if (authorities != null ? !authorities.equals(userForm.authorities) : userForm.authorities != null)
+            return false;
+        if (confirmPassword != null ? !confirmPassword.equals(userForm.confirmPassword) : userForm.confirmPassword != null)
+            return false;
+        if (defaultPageLayoutCode != null ? !defaultPageLayoutCode.equals(userForm.defaultPageLayoutCode) : userForm.defaultPageLayoutCode != null)
+            return false;
+        if (displayName != null ? !displayName.equals(userForm.displayName) : userForm.displayName != null)
+            return false;
+        if (email != null ? !email.equals(userForm.email) : userForm.email != null) return false;
+        if (familyName != null ? !familyName.equals(userForm.familyName) : userForm.familyName != null) return false;
+        if (forgotPasswordHash != null ? !forgotPasswordHash.equals(userForm.forgotPasswordHash) : userForm.forgotPasswordHash != null)
+            return false;
+        if (givenName != null ? !givenName.equals(userForm.givenName) : userForm.givenName != null) return false;
+        if (id != null ? !id.equals(userForm.id) : userForm.id != null) return false;
+        if (openId != null ? !openId.equals(userForm.openId) : userForm.openId != null) return false;
+        if (password != null ? !password.equals(userForm.password) : userForm.password != null) return false;
+        if (status != null ? !status.equals(userForm.status) : userForm.status != null) return false;
+        if (username != null ? !username.equals(userForm.username) : userForm.username != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id != null ? id.hashCode() : 0;
+        result = 31 * result + (authorities != null ? authorities.hashCode() : 0);
+        result = 31 * result + (password != null ? password.hashCode() : 0);
+        result = 31 * result + (username != null ? username.hashCode() : 0);
+        result = 31 * result + (confirmPassword != null ? confirmPassword.hashCode() : 0);
+        result = 31 * result + (forgotPasswordHash != null ? forgotPasswordHash.hashCode() : 0);
+        result = 31 * result + (email != null ? email.hashCode() : 0);
+        result = 31 * result + (openId != null ? openId.hashCode() : 0);
+        result = 31 * result + (defaultPageLayoutCode != null ? defaultPageLayoutCode.hashCode() : 0);
+        result = 31 * result + (givenName != null ? givenName.hashCode() : 0);
+        result = 31 * result + (familyName != null ? familyName.hashCode() : 0);
+        result = 31 * result + (displayName != null ? displayName.hashCode() : 0);
+        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (aboutMe != null ? aboutMe.hashCode() : 0);
+        result = 31 * result + (locked ? 1 : 0);
+        result = 31 * result + (credsExpired ? 1 : 0);
+        result = 31 * result + (expired ? 1 : 0);
+        result = 31 * result + (enabled ? 1 : 0);
+        return result;
+    }
+}
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapper.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapper.java
index 04e583f..7938b8b 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapper.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapper.java
@@ -19,11 +19,10 @@
 
 package org.apache.rave.portal.web.security;
 
-import java.util.Collection;
-
 import org.apache.commons.lang.RandomStringUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.NewAccountService;
 import org.apache.rave.portal.service.UserService;
 import org.springframework.ldap.core.DirContextAdapter;
@@ -32,6 +31,8 @@
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
 
+import java.util.Collection;
+
 /**
  * Mapping class between a Rave User and LDAP user
  */
@@ -86,7 +87,7 @@
     }
 
     private void createRaveUserFromLdapInfo(DirContextOperations ctx, String username) {
-        User newUser = new User();
+        User newUser = new UserImpl();
         newUser.setUsername(username);
 
         if (!ctx.attributeExists(mailAttributeName) || StringUtils.isBlank(ctx.getStringAttribute(mailAttributeName))) {
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java
index 4a8ddd6..4a05fc1 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/tag/RegionWidgetTag.java
@@ -67,11 +67,11 @@
         if (regionWidget != null && getBean().getSupportedWidgetTypes().contains(regionWidget.getWidget().getType()) ) {
             if ( regionWidget.getWidget().isDisableRendering() ) {
                 ScriptManager scriptManager = getBeanFromContext(ScriptManager.class);
-                String widgetScript = String.format(DISABLED_SCRIPT_BLOCK, regionWidget.getRegion().getEntityId(),
-                        regionWidget.getEntityId(),
+                String widgetScript = String.format(DISABLED_SCRIPT_BLOCK, regionWidget.getRegion().getId(),
+                        regionWidget.getId(),
                         StringEscapeUtils.escapeJavaScript(regionWidget.getWidget().getDisableRenderingMessage()),
                         regionWidget.isCollapsed(),
-                        regionWidget.getWidget().getEntityId());
+                        regionWidget.getWidget().getId());
                 scriptManager.registerScriptBlock(widgetScript, ScriptLocation.AFTER_RAVE, RenderScope.CURRENT_REQUEST, getContext());
             } else {
                 writeString(getBean().render(regionWidget, getContext()));
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/ChangePasswordValidator.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/ChangePasswordValidator.java
index bc1cdb2..cdae0c0 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/ChangePasswordValidator.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/ChangePasswordValidator.java
@@ -19,8 +19,8 @@
 
 package org.apache.rave.portal.web.validator;
 
-import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -49,7 +49,7 @@
     @Override
     public void validate(Object target, Errors errors) {
         log.debug("ChangePasswordValidator validator called");
-        User newUser = (User) target;
+        UserForm newUser = (UserForm) target;
         boolean validHash = getUserService().isValidReminderRequest(newUser.getForgotPasswordHash(), minutesValid);
         if (!validHash) {
             errors.rejectValue(FIELD_PASSWORD, "page.changepassword.expired");
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewAccountValidator.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewAccountValidator.java
index 29b5149..1d32711 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewAccountValidator.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewAccountValidator.java
@@ -18,12 +18,10 @@
  */
 package org.apache.rave.portal.web.validator;
 
-import java.util.regex.Pattern;
-
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.validator.routines.EmailValidator;
-import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -32,6 +30,8 @@
 import org.springframework.validation.ObjectError;
 import org.springframework.validation.Validator;
 
+import java.util.regex.Pattern;
+
 @Component
 public class NewAccountValidator implements Validator {
 
@@ -52,12 +52,12 @@
     }
 
     public boolean supports(Class<?> aClass) {
-        return User.class.isAssignableFrom(aClass);
+        return UserForm.class.isAssignableFrom(aClass);
     }
 
     public void validate(Object obj, Errors errors) {
         logger.debug("Validator called");
-        User newUser = (User) obj;
+        UserForm newUser = (UserForm) obj;
 
         validateUsername(errors, newUser);
         validatePassword(errors, newUser);
@@ -67,7 +67,7 @@
         writeResultToLog(errors);
     }
 
-    private void validateUsername(Errors errors, User newUser) {
+    private void validateUsername(Errors errors, UserForm newUser) {
         final String username = newUser.getUsername();
         if (StringUtils.isBlank(username)) {
             errors.rejectValue(FIELD_USERNAME, "username.required");
@@ -85,7 +85,7 @@
         return userService.getUserByUsername(username) != null;
     }
 
-    protected void validatePassword(Errors errors, User newUser) {
+    protected void validatePassword(Errors errors, UserForm newUser) {
         if (StringUtils.isBlank(newUser.getPassword())) {
             errors.rejectValue(FIELD_PASSWORD, "password.required");
             logger.info("Password required");
@@ -95,7 +95,7 @@
         }
     }
 
-    protected void validateConfirmPassword(Errors errors, User newUser) {
+    protected void validateConfirmPassword(Errors errors, UserForm newUser) {
         if (StringUtils.isBlank(newUser.getConfirmPassword())) {
             errors.rejectValue(FIELD_CONFIRM_PASSWORD, "confirmPassword.required");
             logger.info("Confirm Password required");
@@ -105,7 +105,7 @@
         }
     }
 
-    private boolean isConfirmPasswordDifferentThanPassword(User newUser) {
+    private boolean isConfirmPasswordDifferentThanPassword(UserForm newUser) {
         return !(newUser.getConfirmPassword().equals(newUser.getPassword()));
     }
 
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewWidgetValidator.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewWidgetValidator.java
index 66d05e4..4417925 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewWidgetValidator.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/NewWidgetValidator.java
@@ -26,7 +26,7 @@
 import org.springframework.validation.Errors;
 
 /**
- * Validator for adding a new {@link Widget}
+ * Validator for adding a new {@link org.apache.rave.portal.model.Widget}
  */
 @Component
 public class NewWidgetValidator extends WidgetValidator {
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UpdateWidgetValidator.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UpdateWidgetValidator.java
index d773f72..f21cdf9 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UpdateWidgetValidator.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UpdateWidgetValidator.java
@@ -42,7 +42,7 @@
     @Override
     protected final void validateIfWidgetAlreadyExists(Widget widget, Errors errors) {
         Widget existing = widgetService.getWidgetByUrl(widget.getUrl());
-        if (existing == null || existing.getEntityId().equals(widget.getEntityId())) {
+        if (existing == null || existing.getId().equals(widget.getId())) {
             return;
         }
         errors.rejectValue(FIELD_URL, "widget.url.exists");
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UserProfileValidator.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UserProfileValidator.java
index 32ba260..c8a7b9a 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UserProfileValidator.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/UserProfileValidator.java
@@ -95,7 +95,7 @@
 
     private boolean isExistingEmailAddress(User user, String email) {
         final User userByEmail = userService.getUserByEmail(email);
-        return userByEmail != null && !userByEmail.equals(user);
+        return userByEmail != null && !userByEmail.getId().equals(user.getId());
     }
 
         private void writeResultToLog(Errors errors) {
diff --git a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/WidgetValidator.java b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/WidgetValidator.java
index 596154f..6b21c69 100644
--- a/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/WidgetValidator.java
+++ b/rave-components/rave-web/src/main/java/org/apache/rave/portal/web/validator/WidgetValidator.java
@@ -28,7 +28,7 @@
 import org.springframework.validation.Validator;
 
 /**
-Abstract {@link Validator} for {@link Widget}'s
+Abstract {@link Validator} for {@link org.apache.rave.portal.model.Widget}'s
  */
 public abstract class WidgetValidator implements Validator {
     protected static final String FIELD_URL = "url";
@@ -65,7 +65,7 @@
 
     /**
      * Checks if a Widget already exists for this URL.
-     * @param widget {@link Widget} to validate
+     * @param widget {@link org.apache.rave.portal.model.Widget} to validate
      * @param errors {@link Errors}
      */
     protected abstract void validateIfWidgetAlreadyExists(Widget widget, Errors errors);
@@ -86,7 +86,7 @@
     /**
      * Validates fields that may contain a URL
      *
-     * @param widget {@link Widget} to validate
+     * @param widget {@link org.apache.rave.portal.model.Widget} to validate
      * @param errors {@link org.springframework.validation.Errors}
      */
     private void validateUrlFields(Widget widget, Errors errors) {
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/PageApiTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/PageApiTest.java
index 12640db..3b39462 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/PageApiTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/PageApiTest.java
@@ -18,11 +18,8 @@
  */
 package org.apache.rave.portal.web.api.rest;
 
-import java.security.Principal;
-import org.springframework.security.access.AccessDeniedException;
+import org.apache.rave.portal.model.impl.*;
 import org.apache.rave.portal.model.*;
-import org.springframework.util.ClassUtils;
-import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.http.HttpStatus;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.apache.rave.portal.service.PageService;
@@ -39,23 +36,23 @@
  *
  * @author CARLUCCI
  */
-public class PageApiTest {    
-    private PageApi pageApi;    
+public class PageApiTest {
+    private PageApi pageApi;
     private PageService pageService;
     private MockHttpServletResponse response;
-    
+
     private final long PAGE_ID = 1L;
-    
+
     @Before
     public void setUp() {
         response = new MockHttpServletResponse();
         pageService = createMock(PageService.class);
-        pageApi = new PageApi(pageService);     
+        pageApi = new PageApi(pageService);
     }
 
     @Test
     public void getPage_validId() {
-        Page p = new Page();
+        Page p = new PageImpl();
         expect(pageService.getPage(PAGE_ID)).andReturn(p).once();
         replay(pageService);
 
@@ -65,14 +62,14 @@
 
     @Test
     public void getPage_validId_export() {
-        Page p = new Page();
+        Page p = new PageImpl();
         p.setRegions(new ArrayList<Region>());
-        p.setOwner(new User());
-        Region region = new Region();
+        p.setOwner(new UserImpl());
+        Region region = new RegionImpl();
         region.setRegionWidgets(new ArrayList<RegionWidget>());
-        RegionWidget w = new RegionWidget();
+        RegionWidget w = new RegionWidgetImpl();
         w.setPreferences(new ArrayList<RegionWidgetPreference>());
-        w.getPreferences().add(new RegionWidgetPreference());
+        w.getPreferences().add(new RegionWidgetPreferenceImpl());
         region.getRegionWidgets().add(w);
         p.getRegions().add(region);
 
@@ -84,16 +81,16 @@
         assertThat(returned.getOwner(), is(nullValue()));
         assertThat(returned.getRegions().get(0).getRegionWidgets().get(0).getPreferences(), is(nullValue()));
     }
-    
+
     @Test
     public void testDeletePage() {
         pageService.deletePage(PAGE_ID);
         expectLastCall();
         replay(pageService);
-        
+
         pageApi.deletePage(PAGE_ID, response);
-        
-        assertThat(response.getStatus(), is(HttpStatus.NO_CONTENT.value()));   
+
+        assertThat(response.getStatus(), is(HttpStatus.NO_CONTENT.value()));
         verify(pageService);
-    }  
+    }
 }
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/RegionWidgetApiTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/RegionWidgetApiTest.java
index a666398..2f9f181 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/RegionWidgetApiTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/RegionWidgetApiTest.java
@@ -21,15 +21,17 @@
 

 import org.apache.rave.portal.model.RegionWidget;

 import org.apache.rave.portal.model.RegionWidgetPreference;

+import org.apache.rave.portal.model.impl.RegionWidgetImpl;

+import org.apache.rave.portal.model.impl.RegionWidgetPreferenceImpl;

 import org.apache.rave.portal.service.RegionWidgetService;

 import org.apache.rave.portal.web.model.RegionWidgetPreferenceListWrapper;

-import static org.hamcrest.CoreMatchers.*;

 import org.junit.Before;

 import org.junit.Test;

 

 import java.util.Arrays;

 

 import static org.easymock.EasyMock.*;

+import static org.hamcrest.CoreMatchers.sameInstance;

 import static org.junit.Assert.assertThat;

 

 public class RegionWidgetApiTest {

@@ -50,8 +52,8 @@
 

     @Test

     public void replaceAllRegionWidgetPreferences_validParams() {

-        RegionWidgetPreferenceListWrapper LIST_WRAPPER = new RegionWidgetPreferenceListWrapper(Arrays.asList(

-                new RegionWidgetPreference(), new RegionWidgetPreference()

+        RegionWidgetPreferenceListWrapper LIST_WRAPPER = new RegionWidgetPreferenceListWrapper(Arrays.asList( (RegionWidgetPreference)

+                new RegionWidgetPreferenceImpl(), new RegionWidgetPreferenceImpl()

         ));

 

         expect(regionWidgetService.saveRegionWidgetPreferences(VALID_REGION_WIDGET_ID, LIST_WRAPPER.getPreferences())).

@@ -67,8 +69,8 @@
 

     @Test(expected = IllegalArgumentException.class)

     public void replaceAllRegionWidgetPreferences_invalidParams() {

-        RegionWidgetPreferenceListWrapper LIST_WRAPPER = new RegionWidgetPreferenceListWrapper(Arrays.asList(

-                new RegionWidgetPreference(), new RegionWidgetPreference()

+        RegionWidgetPreferenceListWrapper LIST_WRAPPER = new RegionWidgetPreferenceListWrapper(Arrays.asList( (RegionWidgetPreference)

+                new RegionWidgetPreferenceImpl(), new RegionWidgetPreferenceImpl()

         ));

 

         expect(regionWidgetService.saveRegionWidgetPreferences(INVALID_REGION_WIDGET_ID, LIST_WRAPPER.getPreferences())).

@@ -80,7 +82,7 @@
 

     @Test

     public void createOrReplaceRegionWidgetPreference_validParams() {

-        RegionWidgetPreference PREFERENCE = new RegionWidgetPreference(1L, VALID_REGION_WIDGET_ID, VALID_PREFERENCE_NAME,

+        RegionWidgetPreference PREFERENCE = new RegionWidgetPreferenceImpl(VALID_REGION_WIDGET_ID, VALID_PREFERENCE_NAME,

                 VALID_PREFERENCE_VALUE);

 

         expect(regionWidgetService.saveRegionWidgetPreference(VALID_REGION_WIDGET_ID, PREFERENCE)).andReturn(PREFERENCE);

@@ -95,7 +97,7 @@
 

     @Test(expected = IllegalArgumentException.class)

     public void createOrReplaceRegionWidgetPreference_invalidParams_preferenceName() {

-        RegionWidgetPreference PREFERENCE = new RegionWidgetPreference(1L, VALID_REGION_WIDGET_ID, VALID_PREFERENCE_NAME,

+        RegionWidgetPreference PREFERENCE = new RegionWidgetPreferenceImpl(VALID_REGION_WIDGET_ID, VALID_PREFERENCE_NAME,

                 VALID_PREFERENCE_VALUE);

 

         regionWidgetApi.createOrReplaceRegionWidgetPreference(VALID_REGION_WIDGET_ID, "different", PREFERENCE);

@@ -103,7 +105,7 @@
 

     @Test(expected = IllegalArgumentException.class)

     public void createOrReplaceRegionWidgetPreference_invalidParams_regionWidgetId() {

-        RegionWidgetPreference PREFERENCE = new RegionWidgetPreference(1L, VALID_REGION_WIDGET_ID, VALID_PREFERENCE_NAME,

+        RegionWidgetPreference PREFERENCE = new RegionWidgetPreferenceImpl(VALID_REGION_WIDGET_ID, VALID_PREFERENCE_NAME,

                 VALID_PREFERENCE_VALUE);

 

         expect(regionWidgetService.saveRegionWidgetPreference(INVALID_REGION_WIDGET_ID, PREFERENCE)).andThrow(

@@ -117,7 +119,7 @@
     public void updateRegionWidgetCollapsedStatus() {

         final boolean COLLAPSED = true;       

         

-        RegionWidget expectedRegionWidget = new RegionWidget(VALID_REGION_WIDGET_ID);

+        RegionWidget expectedRegionWidget = new RegionWidgetImpl(VALID_REGION_WIDGET_ID);

         expectedRegionWidget.setCollapsed(COLLAPSED);

 

         expect(regionWidgetService.saveRegionWidgetCollapsedState(VALID_REGION_WIDGET_ID, COLLAPSED)).andReturn(expectedRegionWidget); 

diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java
index b28e927..9c6c0c7 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rest/WidgetApiTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.web.api.rest;

 

 import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.*;

 import org.apache.rave.portal.service.*;

 import org.junit.Before;

 import org.junit.Test;

@@ -31,8 +32,10 @@
 import java.util.List;

 

 import static org.easymock.EasyMock.*;

-import static org.hamcrest.CoreMatchers.*;

-import static org.junit.Assert.*;

+import static org.hamcrest.CoreMatchers.is;

+import static org.hamcrest.CoreMatchers.sameInstance;

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertThat;

 

 public class WidgetApiTest {

     private WidgetApi widgetApi;

@@ -46,7 +49,7 @@
     private final Long VALID_USER_ID = 5L;

     private final Long VALID_WIDGET_ID = 10L;

 

-    private User user;

+    private UserImpl user;

     private List<Tag> tagList;

 

     @Before

@@ -57,12 +60,12 @@
         tagService = createMock(TagService.class);

         widgetTagService = createMock(WidgetTagService.class);

 

-        user = new User();

-        user.setEntityId(VALID_USER_ID);

+        user = new UserImpl();

+        user.setId(VALID_USER_ID);

 

         tagList = new ArrayList<Tag>();

-        tagList.add(new Tag(1L, "tag1"));

-        tagList.add(new Tag(2L, "tag2"));

+        tagList.add(new TagImpl("tag1"));

+        tagList.add(new TagImpl("tag2"));

 

         response = createMock(MockHttpServletResponse.class);

         widgetApi = new WidgetApi(widgetRatingService, widgetCommentService, userService, tagService, widgetTagService);

@@ -77,8 +80,8 @@
     public void createWidgetComment() {

         String comment = "new comment";

 

-        Widget widget = new Widget();

-        widget.setEntityId(1L);

+        WidgetImpl widget = new WidgetImpl();

+        widget.setId(1L);

         widget.setComments(new ArrayList<WidgetComment>());

 

         HttpServletResponse httpServletResponse = createMock(HttpServletResponse.class);

@@ -93,13 +96,13 @@
 

     @Test

     public void getWidgetComment() {

-        WidgetComment widgetComment = new WidgetComment();

-        widgetComment.setEntityId(2L);

+        WidgetComment widgetComment = new WidgetCommentImpl();

+        widgetComment.setId(2L);

         expect(widgetCommentService.getWidgetComment(2L)).andReturn(widgetComment);

         replay(widgetCommentService);

 

         WidgetComment foundComment = widgetApi.getWidgetComment(1L, 2L);

-        assertEquals(widgetComment.getEntityId(), foundComment.getEntityId());

+        assertEquals(widgetComment.getId(), foundComment.getId());

 

         verify(widgetCommentService);

     }

@@ -107,10 +110,10 @@
     @Test

     public void updateNonExistentWidgetComment() {

         String message = "message";

-        WidgetComment widgetComment = new WidgetComment();

+        WidgetComment widgetComment = new WidgetCommentImpl();

         widgetComment.setWidgetId(2L);

         widgetComment.setText(message);

-        widgetComment.setUser(new User(VALID_USER_ID, "John.Doe"));

+        widgetComment.setUser(new UserImpl(VALID_USER_ID, "John.Doe"));

 

         expect(userService.getAuthenticatedUser()).andReturn(user);

         expect(widgetCommentService.getWidgetComment(3L)).andReturn(null);

@@ -129,8 +132,8 @@
     @Test

     public void updateWidgetComment() {

         String message = "updated comment";

-        WidgetComment widgetComment = new WidgetComment();

-        widgetComment.setEntityId(2L);

+        WidgetComment widgetComment = new WidgetCommentImpl();

+        widgetComment.setId(2L);

 

         expect(widgetCommentService.getWidgetComment(2L)).andReturn(widgetComment);

         widgetCommentService.saveWidgetComment(widgetComment);

@@ -175,17 +178,17 @@
 

     @Test

     public void updateWidgetRating() {

-        WidgetRating widgetRating = new WidgetRating();

+        WidgetRating widgetRating = new WidgetRatingImpl();

         widgetRating.setScore(5);

-        widgetRating.setUserId(2L);

+        widgetRating.setUserId(5L);

         widgetRating.setWidgetId(1L);

         expect(userService.getAuthenticatedUser()).andReturn(user);

-        widgetRatingService.saveWidgetRating(widgetRating);

+        widgetRatingService.saveWidgetRating(eq(widgetRating));

         expectLastCall();

         response.setStatus(HttpStatus.NO_CONTENT.value());

         replay(userService, widgetRatingService, response);

 

-        User user = new User(2L);

+        User user = new UserImpl(2L);

         widgetApi.setWidgetRating(1L, 5, response);

 

         verify(widgetRatingService, userService, response);

@@ -194,8 +197,8 @@
     @Test

     public void getAllUsers() {

         List<Person> persons = new ArrayList<Person>();

-        persons.add(new Person());

-        persons.add(new Person());

+        persons.add(new PersonImpl());

+        persons.add(new PersonImpl());

 

         expect(userService.getAllByAddedWidget(VALID_WIDGET_ID)).andReturn(persons);

         replay(userService);

@@ -225,14 +228,16 @@
     @Test

     public void createWidgetTag_newTag() {

         final String TAG_TEXT = "mytag";

-        Tag tag = new Tag(1L, TAG_TEXT);

-        WidgetTag widgetTag = new WidgetTag();

+        TagImpl tag = new TagImpl();

+        tag.setKeyword(TAG_TEXT);

+        WidgetTag widgetTag = new WidgetTagImpl();

         widgetTag.setTag(tag);

+        widgetTag.setWidgetId(VALID_WIDGET_ID);

                         

         expect(widgetTagService.getWidgetTagByWidgetIdAndKeyword(VALID_WIDGET_ID, TAG_TEXT)).andReturn(null);

         expect(userService.getAuthenticatedUser()).andReturn(user);

         expect(tagService.getTagByKeyword(TAG_TEXT)).andReturn(null);

-        widgetTagService.saveWidgetTag(widgetTag);

+        widgetTagService.saveWidgetTag(isA(WidgetTag.class));

         expectLastCall();

         replay(widgetTagService, userService, tagService);

         widgetApi.createWidgetTag(VALID_WIDGET_ID, TAG_TEXT, response);

@@ -242,14 +247,15 @@
     @Test

     public void createWidgetTag_newTag_existsForOtherWidget() {

         final String TAG_TEXT = "mytag";

-        Tag tag = new Tag(1L, TAG_TEXT);

-        WidgetTag widgetTag = new WidgetTag();

+        TagImpl tag = new TagImpl();

+        tag.setKeyword(TAG_TEXT);

+        WidgetTagImpl widgetTag = new WidgetTagImpl();

         widgetTag.setTag(tag);

 

         expect(widgetTagService.getWidgetTagByWidgetIdAndKeyword(VALID_WIDGET_ID, TAG_TEXT)).andReturn(null);

         expect(userService.getAuthenticatedUser()).andReturn(user);

         expect(tagService.getTagByKeyword(TAG_TEXT)).andReturn(tag);

-        widgetTagService.saveWidgetTag(widgetTag);

+        widgetTagService.saveWidgetTag(isA(WidgetTag.class));

         expectLastCall();

         replay(widgetTagService, userService, tagService);

         widgetApi.createWidgetTag(VALID_WIDGET_ID, TAG_TEXT, response);

@@ -259,8 +265,9 @@
     @Test

     public void createWidgetTag_nullText() {

         final String TAG_TEXT = null;

-        Tag tag = new Tag(1L, TAG_TEXT);

-        WidgetTag widgetTag = new WidgetTag();

+        TagImpl tag = new TagImpl();

+        tag.setKeyword(TAG_TEXT);

+        WidgetTagImpl widgetTag = new WidgetTagImpl();

         widgetTag.setTag(tag);

 

         widgetApi.createWidgetTag(VALID_WIDGET_ID, TAG_TEXT, response);

@@ -269,8 +276,9 @@
     @Test

     public void createWidgetTag_emptyText() {

         final String TAG_TEXT = "      ";

-        Tag tag = new Tag(1L, TAG_TEXT);

-        WidgetTag widgetTag = new WidgetTag();

+        TagImpl tag = new TagImpl();

+        tag.setKeyword(TAG_TEXT);

+        WidgetTagImpl widgetTag = new WidgetTagImpl();

         widgetTag.setTag(tag);

 

         widgetApi.createWidgetTag(VALID_WIDGET_ID, TAG_TEXT, response);

@@ -279,9 +287,9 @@
     @Test

     public void createWidgetTag_existingTag() {

         final String TAG_TEXT = "mytag";

-        Tag tag = new Tag(1L, TAG_TEXT);

-        WidgetTag widgetTag = new WidgetTag();

-        widgetTag.setEntityId(9L);

+        TagImpl tag = new TagImpl();

+        tag.setKeyword(TAG_TEXT);

+        WidgetTagImpl widgetTag = new WidgetTagImpl();

         widgetTag.setTag(tag);

 

         expect(widgetTagService.getWidgetTagByWidgetIdAndKeyword(VALID_WIDGET_ID, TAG_TEXT)).andReturn(widgetTag);

diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java
index 4327c5e..5820e9c 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java
@@ -22,6 +22,7 @@
 import org.apache.rave.portal.model.Page;

 import org.apache.rave.portal.model.Region;

 import org.apache.rave.portal.model.RegionWidget;

+import org.apache.rave.portal.model.impl.*;

 import org.apache.rave.portal.service.PageService;

 import org.apache.rave.portal.web.api.rpc.model.RpcResult;

 import org.junit.Before;

@@ -42,7 +43,7 @@
     private final int NEW_POSITION = 3;

     private final long PAGE_ID = 20L;

     private final long PAGE_2_ID = 38L;

-    

+

     private Page page, page2;

 

 

@@ -50,9 +51,9 @@
     public void setup() {

         pageService = createMock(PageService.class);

         pageApi = new PageApi(pageService);

-        

-        page = new Page(PAGE_ID);

-        page2 = new Page(PAGE_2_ID);

+

+        page = new PageImpl(PAGE_ID);

+        page2 = new PageImpl(PAGE_2_ID);

     }

 

     @Test

@@ -60,7 +61,7 @@
         final long TO_REGION = 1;

         final long FROM_REGION = 2;

 

-        expect(pageService.moveRegionWidget(REGION_WIDGET_ID, NEW_POSITION, TO_REGION, FROM_REGION)).andReturn(new RegionWidget());

+        expect(pageService.moveRegionWidget(REGION_WIDGET_ID, NEW_POSITION, TO_REGION, FROM_REGION)).andReturn(new RegionWidgetImpl());

         replay(pageService);

         RpcResult<RegionWidget> result = pageApi.moveWidgetOnPage(REGION_WIDGET_ID, NEW_POSITION, TO_REGION, FROM_REGION);

         verify(pageService);

@@ -103,14 +104,14 @@
         assertThat(result.isError(), is(true));

         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INTERNAL_ERROR));

         assertThat(result.getErrorMessage(), is(equalTo(INTERNAL_ERROR_MESSAGE)));

-    }    

-    

+    }

+

     @Test

     public void addWidget_validParams() {

         final int PAGE_ID = 1;

         final long WIDGET_ID = 2;

 

-        expect(pageService.addWidgetToPage(PAGE_ID, WIDGET_ID)).andReturn(new RegionWidget());

+        expect(pageService.addWidgetToPage(PAGE_ID, WIDGET_ID)).andReturn(new RegionWidgetImpl());

         replay(pageService);

         RpcResult result = pageApi.addWidgetToPage(PAGE_ID, WIDGET_ID);

         verify(pageService);

@@ -156,7 +157,7 @@
     @Test

     public void deleteWidget_validParams() {

         final long WIDGET_ID = 3;

-        expect(pageService.removeWidgetFromPage(WIDGET_ID)).andReturn(new Region());

+        expect(pageService.removeWidgetFromPage(WIDGET_ID)).andReturn(new RegionImpl());

         replay(pageService);

 

         RpcResult<Region> result = pageApi.removeWidgetFromPage(WIDGET_ID);

@@ -196,13 +197,13 @@
         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INTERNAL_ERROR));

         assertThat(result.getErrorMessage(), is(equalTo(INTERNAL_ERROR_MESSAGE)));

     }

-    

+

     @Test

     public void addPage_validParams() {

         final String PAGE_NAME = "My New Page";

         final String PAGE_LAYOUT_CODE = "layout1";

 

-        expect(pageService.addNewUserPage(PAGE_NAME, PAGE_LAYOUT_CODE)).andReturn(new Page());

+        expect(pageService.addNewUserPage(PAGE_NAME, PAGE_LAYOUT_CODE)).andReturn(new PageImpl());

         replay(pageService);

         RpcResult result = pageApi.addPage(PAGE_NAME, PAGE_LAYOUT_CODE);

         verify(pageService);

@@ -212,7 +213,7 @@
         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.NO_ERROR));

         assertThat(result.getErrorMessage(), is(nullValue()));

     }

-    

+

     @Test

     public void addPage_invalidParams() {

         final String PAGE_NAME = "My New Page";

@@ -228,7 +229,7 @@
         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INVALID_PARAMS));

         assertThat(result.getErrorMessage(), is(equalTo(PARAM_ERROR_MESSAGE)));

     }

-    

+

     @Test

     public void addPage_internalError() {

         final String PAGE_NAME = "My New Page";

@@ -244,14 +245,14 @@
         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INTERNAL_ERROR));

         assertThat(result.getErrorMessage(), is(equalTo(INTERNAL_ERROR_MESSAGE)));

     }

-    

+

     @Test

     public void getPage() {

         expect(pageService.getPage(PAGE_ID)).andReturn(page);

         replay(pageService);

-        

+

         RpcResult result = pageApi.getPage(PAGE_ID);

-        

+

         verify(pageService);

         assertThat(result, is(notNullValue()));

         assertThat((Page)result.getResult(), is (page));

@@ -265,9 +266,9 @@
         String layoutName = "layout";

         expect(pageService.updatePage(PAGE_ID, pageName, layoutName)).andReturn(page);

         replay(pageService);

-        

+

         RpcResult result = pageApi.updatePageProperties(PAGE_ID, pageName, layoutName);

-        

+

         verify(pageService);

         assertThat(result, is(notNullValue()));

         assertThat((Page)result.getResult(), is (page));

@@ -275,40 +276,40 @@
         assertThat(result.getErrorCode(), is (RpcResult.ErrorCode.NO_ERROR));

         assertThat(result.getErrorMessage(), is(nullValue()));

     }

-    

+

     @Test

     public void movePage_nonNullMoveAfterPageId() {

         expect(pageService.movePage(PAGE_ID, PAGE_2_ID)).andReturn(page);

         replay(pageService);

-                

-        RpcResult result = pageApi.movePage(PAGE_ID, PAGE_2_ID);                

-        

-        verify(pageService);        

+

+        RpcResult result = pageApi.movePage(PAGE_ID, PAGE_2_ID);

+

+        verify(pageService);

         assertThat(result, is(notNullValue()));

         assertThat((Page)result.getResult(), is(page));

         assertThat(result.isError(), is(false));

         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.NO_ERROR));

         assertThat(result.getErrorMessage(), is(nullValue()));

-    }    

-    

+    }

+

     @Test

     public void movePage_nullMoveAfterPageId() {

         expect(pageService.movePageToDefault(PAGE_2_ID)).andReturn(page2);

         replay(pageService);

-                

-        RpcResult result = pageApi.movePage(PAGE_2_ID, null);                

-        

-        verify(pageService);        

+

+        RpcResult result = pageApi.movePage(PAGE_2_ID, null);

+

+        verify(pageService);

         assertThat(result, is(notNullValue()));

         assertThat((Page)result.getResult(), is(page2));

         assertThat(result.isError(), is(false));

         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.NO_ERROR));

         assertThat(result.getErrorMessage(), is(nullValue()));

-    }      

-    

+    }

+

     @Test

-    public void moveWidgetToPage_validParams() {      

-        expect(pageService.moveRegionWidgetToPage(REGION_WIDGET_ID, PAGE_2_ID)).andReturn(new RegionWidget());

+    public void moveWidgetToPage_validParams() {

+        expect(pageService.moveRegionWidgetToPage(REGION_WIDGET_ID, PAGE_2_ID)).andReturn(new RegionWidgetImpl());

         replay(pageService);

         RpcResult<RegionWidget> result = pageApi.moveWidgetToPage(PAGE_2_ID, REGION_WIDGET_ID);

         verify(pageService);

@@ -320,7 +321,7 @@
     }

 

     @Test

-    public void moveWidgetToPage_invalidParams() {    

+    public void moveWidgetToPage_invalidParams() {

         expect(pageService.moveRegionWidgetToPage(REGION_WIDGET_ID, PAGE_2_ID)).andThrow(new IllegalArgumentException(PARAM_ERROR_MESSAGE));

         replay(pageService);

 

@@ -345,5 +346,5 @@
         assertThat(result.isError(), is(true));

         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INTERNAL_ERROR));

         assertThat(result.getErrorMessage(), is(equalTo(INTERNAL_ERROR_MESSAGE)));

-    }  

+    }

 }

diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ChangePasswordControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ChangePasswordControllerTest.java
index 3e5f688..89ee699 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ChangePasswordControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ChangePasswordControllerTest.java
@@ -19,14 +19,8 @@
 
 package org.apache.rave.portal.web.controller;
 
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.ChangePasswordValidator;
@@ -38,6 +32,10 @@
 import org.springframework.validation.DirectFieldBindingResult;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
 /**
  * @version "$Id$"
  */
@@ -71,7 +69,7 @@
     public void testUpdate() throws Exception {
         final Model model = createNiceMock(Model.class);
         RedirectAttributes redirectAttributes = createNiceMock(RedirectAttributes.class);
-        User newUser = new User();
+        UserForm newUser = new UserForm();
         replay(redirectAttributes);
         replay(model);
         BindingResult results = new DirectFieldBindingResult(newUser, ModelKeys.USER);
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/NewAccountControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/NewAccountControllerTest.java
index b1fbebd..c341fa7 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/NewAccountControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/NewAccountControllerTest.java
@@ -19,19 +19,13 @@
 
 package org.apache.rave.portal.web.controller;
 
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertThat;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.CaptchaService;
 import org.apache.rave.portal.service.NewAccountService;
 import org.apache.rave.portal.service.UserService;
 import org.apache.rave.portal.service.impl.ReCaptchaService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.NewAccountValidator;
@@ -45,6 +39,12 @@
 import org.springframework.validation.ObjectError;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertThat;
+
 
 /**
  * This is a test class for NewAccountController, which is used to make new user accounts through
@@ -93,7 +93,7 @@
 	@Test
 	public void create_UsernameNotSpecified() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = ""; //no username specified
 		final String password = "password";
@@ -123,12 +123,12 @@
 	@Test
 	public void create_UsernameAlreadyExists() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "canonical"; //specified username already exists in database
 		final String password = "password";
 		final String confirmPassword = password;
-		final User existingUser = new User();
+		final User existingUser = new UserImpl();
 		List<ObjectError> errorList = new ArrayList<ObjectError>();
 		final ObjectError error = new ObjectError("username.exists", "Username already exists");
 
@@ -160,7 +160,7 @@
 	@Test
 	public void create_InvalidUsernameLength() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "u"; //username length less than 2 characters
 		final String password = "password";
@@ -190,7 +190,7 @@
 	@Test
 	public void create_PasswordNotSpecified() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "username";
 		final String password = ""; //password not specified
@@ -220,7 +220,7 @@
 	@Test
 	public void create_ConfirmPasswordNotSpecified() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "usename";
 		final String password = "pasword";
@@ -249,7 +249,7 @@
 	@Test
 	public void create_InvalidPasswordLength() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "usename";
 		final String password = "pas"; //invalid length password
@@ -277,7 +277,7 @@
 	@Test
 	public void create_PasswordMismatchCaseOne() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "username";
 		final String password = "password";
@@ -305,7 +305,7 @@
 	@Test
 	public void create_PasswordMismatchCaseTwo() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "username";
 		final String password = "password";
@@ -333,7 +333,7 @@
 	@Test
 	public void create_BlankFormSubmitted() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = ""; //Username not specified
 		final String password = ""; //Password not specified
@@ -366,7 +366,7 @@
 	@Test
 	public void create_ValidFormSubmitted() {
 		final Model model = createNiceMock(Model.class);
-		final User User = new User();
+		final UserForm User = new UserForm();
 		final BindingResult errors = createNiceMock(BindingResult.class);
 		final String username = "username"; //Username not specified
 		final String password = "password"; //Password not specified
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java
index a2b0773..75d0cee 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/PageControllerTest.java
@@ -19,28 +19,31 @@
 

 package org.apache.rave.portal.web.controller;

 

-import org.apache.rave.portal.service.PageLayoutService;

-import org.apache.rave.portal.web.controller.util.MockHttpUtil;

-import org.springframework.mock.web.MockHttpServletRequest;

+import org.apache.rave.portal.model.Page;

 import org.apache.rave.portal.model.PageInvitationStatus;

 import org.apache.rave.portal.model.PageLayout;

-import org.apache.rave.portal.model.Page;

 import org.apache.rave.portal.model.PageUser;

-import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.impl.PageImpl;

+import org.apache.rave.portal.model.impl.PageLayoutImpl;

+import org.apache.rave.portal.model.impl.PageUserImpl;

+import org.apache.rave.portal.model.impl.UserImpl;

+import org.apache.rave.portal.service.PageLayoutService;

 import org.apache.rave.portal.service.PageService;

 import org.apache.rave.portal.service.UserService;

+import org.apache.rave.portal.web.controller.util.MockHttpUtil;

 import org.apache.rave.portal.web.util.ModelKeys;

 import org.apache.rave.portal.web.util.ViewNames;

 import org.junit.Before;

 import org.junit.Test;

+import org.springframework.mock.web.MockHttpServletRequest;

 import org.springframework.ui.ExtendedModelMap;

 import org.springframework.ui.Model;

 

 import java.util.ArrayList;

 import java.util.List;

 

-import static org.hamcrest.CoreMatchers.*;

 import static org.easymock.EasyMock.*;

+import static org.hamcrest.CoreMatchers.*;

 import static org.junit.Assert.assertThat;

 

 public class PageControllerTest {

@@ -49,22 +52,23 @@
     private PageLayoutService pageLayoutService;

     private PageController pageController;

     private MockHttpServletRequest request;

-    

+

     private Model model;

     private Page defaultPage, otherPage;

     private PageUser defaultPageUser, otherPageUser;

     private List<Page> allPages;

     private List<PageLayout> allPageLayouts;

-    

+

     private final Long DEFAULT_PAGE_ID = 99L;

     private final Long OTHER_PAGE_ID = 22L;

     private final Long USER_ID = 1L;

     private final String VALID_PAGE_LAYOUT_CODE = "layout98";

-    private User validUser;

+    private UserImpl validUser;

     private PageLayout validPageLayout;

 

     @Before

     public void setup() {

+

         userService = createMock(UserService.class);

         pageService = createMock(PageService.class);

         pageLayoutService = createMock(PageLayoutService.class);

@@ -72,144 +76,146 @@
         model = new ExtendedModelMap();

         request = new MockHttpServletRequest();

 

-        validPageLayout = new PageLayout();

-        validPageLayout.setEntityId(33L);

+        validUser = new UserImpl(USER_ID);

+        validPageLayout = new PageLayoutImpl();

         validPageLayout.setCode(VALID_PAGE_LAYOUT_CODE);

-

-        validUser = new User(USER_ID);

-

-        defaultPage = new Page(DEFAULT_PAGE_ID, validUser);

-        defaultPage.setPageLayout(validPageLayout);

-        defaultPageUser = new PageUser(validUser, defaultPage, 1L);

+        defaultPageUser = new PageUserImpl(validUser, defaultPage, 1L);

         defaultPageUser.setPageStatus(PageInvitationStatus.OWNER);

-        defaultPage.setMembers(new ArrayList<PageUser>());

-        defaultPage.getMembers().add(defaultPageUser);

 

-        otherPage = new Page(OTHER_PAGE_ID, validUser);

+        validUser.setDefaultPageLayout(validPageLayout);

+

+        defaultPage = new PageImpl(DEFAULT_PAGE_ID, validUser);

+        defaultPage.setPageLayout(validPageLayout);

+

+        List<PageUser> members = new ArrayList<PageUser>();

+        members.add(defaultPageUser);

+        defaultPage.setMembers(members);

+

+        otherPage = new PageImpl(OTHER_PAGE_ID, validUser);

         otherPage.setPageLayout(validPageLayout);

-        otherPageUser = new PageUser(validUser, otherPage, 2L);

+        otherPageUser = new PageUserImpl(validUser, otherPage, 2L);

         otherPageUser.setPageStatus(PageInvitationStatus.OWNER);

-        otherPage.setMembers(new ArrayList<PageUser>());

-        otherPage.getMembers().add(otherPageUser);

+

+        List<PageUser> members2 = new ArrayList<PageUser>();

+        members2.add(otherPageUser);

+        otherPage.setMembers(members2);

 

         allPages = new ArrayList<Page>();

-        allPages.add(defaultPage);   

+        allPages.add(defaultPage);

         allPages.add(otherPage);

 

         allPageLayouts = new ArrayList<PageLayout>();

         allPageLayouts.add(validPageLayout);

-

-        validUser.setDefaultPageLayout(validPageLayout);

     }

 

     @SuppressWarnings("unchecked")

     @Test

     public void view_pageId() {

         MockHttpUtil.setupRequestAsNonMobileUserAgent(request);

-        

-        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 

+

+        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes();

         expect(pageService.getAllUserPages(USER_ID)).andReturn(allPages);

         expect(pageService.getPageFromList(OTHER_PAGE_ID, allPages)).andReturn(otherPage);

         expect(pageLayoutService.getAllUserSelectable()).andReturn(allPageLayouts);

         replay(userService, pageService, pageLayoutService);

 

         String results = pageController.view(OTHER_PAGE_ID, model, request);

-        

+

         assertThat(results, equalTo(ViewNames.getPageView(VALID_PAGE_LAYOUT_CODE)));

         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(otherPage));

         assertThat((List<Page>) model.asMap().get(ModelKeys.PAGES), equalTo(allPages));

         assertThat((List<PageLayout>) model.asMap().get(ModelKeys.PAGE_LAYOUTS), sameInstance(allPageLayouts));

-        

+

         verify(userService, pageService, pageLayoutService);

     }

-    

+

     @SuppressWarnings("unchecked")

     @Test

-    public void view_pageId_mobileClient() {       

+    public void view_pageId_mobileClient() {

         MockHttpUtil.setupRequestAsMobileUserAgent(request);

-        

-        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 

+

+        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes();

         expect(pageService.getAllUserPages(USER_ID)).andReturn(allPages);

         expect(pageService.getPageFromList(OTHER_PAGE_ID, allPages)).andReturn(otherPage);

         expect(pageLayoutService.getAllUserSelectable()).andReturn(allPageLayouts);

         replay(userService, pageService, pageLayoutService);

 

         String results = pageController.view(OTHER_PAGE_ID, model, request);

-        

+

         assertThat(results, equalTo(ViewNames.MOBILE_HOME));

         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(otherPage));

         assertThat((List<Page>) model.asMap().get(ModelKeys.PAGES), equalTo(allPages));

         assertThat((List<PageLayout>) model.asMap().get(ModelKeys.PAGE_LAYOUTS), sameInstance(allPageLayouts));

-        

+

         verify(userService, pageService, pageLayoutService);

     }

-    

+

     @SuppressWarnings("unchecked")

     @Test

     public void view_pageId_zeroExistingPages() {

         MockHttpUtil.setupRequestAsNonMobileUserAgent(request);

         List<Page> pages = new ArrayList<Page>();

-        

+

         assertThat(pages.isEmpty(), is(true));

-        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 

+        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes();

         expect(pageService.getAllUserPages(USER_ID)).andReturn(pages).times(2);

-        expect(pageService.addNewDefaultUserPage(validUser.getEntityId())).andReturn(defaultPage);

+        expect(pageService.addNewDefaultUserPage(validUser.getId())).andReturn(defaultPage);

         expect(pageService.getPageFromList(OTHER_PAGE_ID, pages)).andReturn(defaultPage);

         expect(pageLayoutService.getAllUserSelectable()).andReturn(allPageLayouts);

         replay(userService, pageService, pageLayoutService);

-        

+

         String results = pageController.view(OTHER_PAGE_ID, model, request);

-        

+

         assertThat(results, equalTo(ViewNames.getPageView(VALID_PAGE_LAYOUT_CODE)));

         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(defaultPage));

         assertThat((List<Page>) model.asMap().get(ModelKeys.PAGES), sameInstance(pages));

         assertThat((List<PageLayout>) model.asMap().get(ModelKeys.PAGE_LAYOUTS), sameInstance(allPageLayouts));

-        

+

         verify(userService, pageService, pageLayoutService);

-    }    

-    

+    }

+

     @SuppressWarnings("unchecked")

     @Test

     public void viewDefault_pageId() {

         MockHttpUtil.setupRequestAsNonMobileUserAgent(request);

-        

-        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 

+

+        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes();

         expect(pageService.getAllUserPages(USER_ID)).andReturn(allPages);

         expect(pageService.getDefaultPageFromList(allPages)).andReturn(defaultPage);

         expect(pageLayoutService.getAllUserSelectable()).andReturn(allPageLayouts);

         replay(userService, pageService, pageLayoutService);

 

         String results = pageController.viewDefault(model, request);

-        

+

         assertThat(results, equalTo(ViewNames.getPageView(VALID_PAGE_LAYOUT_CODE)));

         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(defaultPage));

         assertThat((List<Page>) model.asMap().get(ModelKeys.PAGES), equalTo(allPages));

         assertThat((List<PageLayout>) model.asMap().get(ModelKeys.PAGE_LAYOUTS), sameInstance(allPageLayouts));

-        

+

         verify(userService, pageService, pageLayoutService);

     }

-    

+

     @SuppressWarnings("unchecked")

     @Test

     public void viewDefault_pageId_zeroExistingPages() {

         MockHttpUtil.setupRequestAsNonMobileUserAgent(request);

         List<Page> pages = new ArrayList<Page>();

-        

+

         assertThat(pages.isEmpty(), is(true));

-        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes(); 

+        expect(userService.getAuthenticatedUser()).andReturn(validUser).anyTimes();

         expect(pageService.getAllUserPages(USER_ID)).andReturn(pages).times(2);

-        expect(pageService.addNewDefaultUserPage(validUser.getEntityId())).andReturn(defaultPage);

+        expect(pageService.addNewDefaultUserPage(validUser.getId())).andReturn(defaultPage);

         expect(pageService.getDefaultPageFromList(pages)).andReturn(defaultPage);

         expect(pageLayoutService.getAllUserSelectable()).andReturn(allPageLayouts);

         replay(userService, pageService, pageLayoutService);

 

         String results = pageController.viewDefault(model, request);

-        

+

         assertThat(results, equalTo(ViewNames.getPageView(VALID_PAGE_LAYOUT_CODE)));

         assertThat((Page) model.asMap().get(ModelKeys.PAGE), sameInstance(defaultPage));

         assertThat((List<Page>) model.asMap().get(ModelKeys.PAGES), sameInstance(pages));

         assertThat((List<PageLayout>) model.asMap().get(ModelKeys.PAGE_LAYOUTS), sameInstance(allPageLayouts));

-        

+

         verify(userService, pageService, pageLayoutService);

     }

 }

diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ProfileControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ProfileControllerTest.java
index 2df6b70..e114986 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ProfileControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ProfileControllerTest.java
@@ -19,15 +19,15 @@
 
 package org.apache.rave.portal.web.controller;
 
-import static org.easymock.EasyMock.*;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.*;
-
 import org.apache.rave.portal.model.Page;
 import org.apache.rave.portal.model.PageLayout;
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.PageImpl;
+import org.apache.rave.portal.model.impl.PageLayoutImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.PageService;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.hamcrest.CoreMatchers;
@@ -39,6 +39,11 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
 /**
  * Test class for {@link ProfileController}
  */
@@ -65,13 +70,12 @@
 		pageService = createMock(PageService.class);
 		profileController = new ProfileController(userService, pageService);
 
-        validPageLayout = new PageLayout();
-        validPageLayout.setEntityId(33L);
+        validPageLayout = new PageLayoutImpl();
         validPageLayout.setCode(VALID_PAGE_LAYOUT_CODE);
 
-        defaultPage = new Page(DEFAULT_PAGE_ID);
+        defaultPage = new PageImpl(DEFAULT_PAGE_ID);
         defaultPage.setPageLayout(validPageLayout);
-        otherPage = new Page(OTHER_PAGE_ID);
+        otherPage = new PageImpl(OTHER_PAGE_ID);
         otherPage.setPageLayout(validPageLayout);
 
         allProfilePages = new ArrayList<Page>();
@@ -85,20 +89,20 @@
 	@Test
 	public void viewPerson_ShouldAddAttributeForUser() {
 		//creating a mock user
-		final User user = new User();
+		final UserImpl user = new UserImpl();
 		final ModelMap model = new ModelMap();
 		final int modelSize = 4;
 		final String username="Canonical";
         user.setUsername(username);
-        user.setEntityId(USER_ID);
+        user.setId(USER_ID);
 		String userProfile = new String(ModelKeys.USER_PROFILE);
-        Page personProfile = new Page();
-        PageLayout pageLayout = new PageLayout();
+        Page personProfile = new PageImpl();
+        PageLayout pageLayout = new PageLayoutImpl();
         pageLayout.setCode(VALID_PAGE_LAYOUT_CODE);
         personProfile.setPageLayout(pageLayout);
 
 		expect(userService.getUserByUsername(username)).andReturn(user).once();
-        expect(pageService.getPersonProfilePage(user.getEntityId())).andReturn(personProfile);
+        expect(pageService.getPersonProfilePage(user.getId())).andReturn(personProfile);
 
 		replay(userService, pageService);
 
@@ -128,8 +132,8 @@
         final ModelMap model = new ModelMap();
         final int modelSize = 4;
         final String username="Canonical";
-        Page personProfile = new Page();
-        PageLayout pageLayout = new PageLayout();
+        Page personProfile = new PageImpl();
+        PageLayout pageLayout = new PageLayoutImpl();
         pageLayout.setCode("person_profile");
         personProfile.setPageLayout(pageLayout);
 
@@ -152,7 +156,7 @@
 		String userProfile = new String(ModelKeys.USER_PROFILE);
 
 		//creating a mock authenticated user
-		final User authUser = new User();
+		final User authUser = new UserImpl();
         authUser.setUsername(USERNAME);
 		//set existing status
 		authUser.setStatus("Single");
@@ -163,7 +167,7 @@
 		authUser.setEmail("testuser@rave.com");
 
 		//creating a mock updated user
-		final User updatedUser = new User();
+		final UserForm updatedUser = new UserForm();
 		//set the updated status
 		updatedUser.setStatus("Married");
 		updatedUser.setGivenName("Test");
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ReminderControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ReminderControllerTest.java
index 3282a37..50f60df 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ReminderControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/ReminderControllerTest.java
@@ -19,10 +19,10 @@
 
 package org.apache.rave.portal.web.controller;
 
-import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.CaptchaService;
 import org.apache.rave.portal.service.UserService;
 import org.apache.rave.portal.service.impl.ReCaptchaService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.NewPasswordValidator;
@@ -83,7 +83,7 @@
     @Test
     public void testCreate() throws Exception {
         Model model = createNiceMock(Model.class);
-        User User = new User();
+        UserForm User = new UserForm();
         BindingResult results = new DirectFieldBindingResult(User, ModelKeys.USER);
         RedirectAttributes redirectAttributes = createNiceMock(RedirectAttributes.class);
         replay(redirectAttributes);
@@ -109,7 +109,7 @@
         assertThat(viewResult, CoreMatchers.equalTo(ViewNames.USERNAME_REQUEST));
         // password part:
         model = createNiceMock(Model.class);
-        User = new User();
+        User = new UserForm();
         results = new DirectFieldBindingResult(User, ModelKeys.USER);
         redirectAttributes = createNiceMock(RedirectAttributes.class);
         replay(redirectAttributes);
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java
index 322edca..fa78dab 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/WidgetStoreControllerTest.java
@@ -22,15 +22,12 @@
 
 import org.apache.rave.portal.model.Category;
 import org.apache.rave.portal.model.Tag;
-import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.model.util.WidgetStatistics;
-import org.apache.rave.portal.service.PortalPreferenceService;
-import org.apache.rave.portal.service.TagService;
-import org.apache.rave.portal.service.CategoryService;
-import org.apache.rave.portal.service.UserService;
-import org.apache.rave.portal.service.WidgetService;
+import org.apache.rave.portal.service.*;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.PortalPreferenceKeys;
 import org.apache.rave.portal.web.util.ViewNames;
@@ -48,18 +45,9 @@
 import java.util.Map;
 
 import static junit.framework.Assert.assertEquals;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.sameInstance;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
 
 
 /**
@@ -73,14 +61,14 @@
     private WidgetService widgetService;
     private TagService tagService;
     private CategoryService categoryService;
-    private User validUser;
+    private UserImpl validUser;
     private WidgetStatistics widgetStatistics;
     private Map<Long, WidgetStatistics> allWidgetStatisticsMap;
 
     @Before
     public void setup() {
-        validUser = new User();
-        validUser.setEntityId(1L);
+        validUser = new UserImpl();
+        validUser.setId(1L);
         widgetStatistics = new WidgetStatistics();
 
         allWidgetStatisticsMap = new HashMap<Long, WidgetStatistics>();
@@ -111,7 +99,7 @@
         SearchResult<Widget> emptyResult = new SearchResult<Widget>(widgets, 0);
 
         expect(widgetService.getPublishedWidgets(0, 10)).andReturn(emptyResult);
-        expect(widgetService.getAllWidgetStatistics(validUser.getEntityId())).andReturn(allWidgetStatisticsMap);
+        expect(widgetService.getAllWidgetStatistics(validUser.getId())).andReturn(allWidgetStatisticsMap);
         replay(widgetService);
 
         String view = controller.view(model, REFERRER_ID, 0);
@@ -133,8 +121,8 @@
         List<Widget> widgets = new ArrayList<Widget>();
         SearchResult<Widget> emptyResult = new SearchResult<Widget>(widgets, 0);
 
-        expect(widgetService.getWidgetsByOwner(validUser.getEntityId(), 0, 10)).andReturn(emptyResult);
-        expect(widgetService.getAllWidgetStatistics(validUser.getEntityId())).andReturn(allWidgetStatisticsMap);
+        expect(widgetService.getWidgetsByOwner(validUser.getId(), 0, 10)).andReturn(emptyResult);
+        expect(widgetService.getAllWidgetStatistics(validUser.getId())).andReturn(allWidgetStatisticsMap);
         replay(widgetService);
 
         String view = controller.viewMine(model, REFERRER_ID, 0);
@@ -153,13 +141,13 @@
     @Test
     public void viewWidget() {
         Model model = new ExtendedModelMap();
-        Widget w = new Widget(1L, "http://example.com/widget.xml");
+        Widget w = new WidgetImpl(1L, "http://example.com/widget.xml");
 
-        expect(widgetService.getAllWidgetStatistics(validUser.getEntityId())).andReturn(allWidgetStatisticsMap);
+        expect(widgetService.getAllWidgetStatistics(validUser.getId())).andReturn(allWidgetStatisticsMap);
         expect(tagService.getAllTags()).andReturn(new ArrayList<Tag>());
         expect(categoryService.getAll()).andReturn(new ArrayList<Category>());
         expect(widgetService.getWidget(WIDGET_ID)).andReturn(w);
-        expect(widgetService.getWidgetStatistics(WIDGET_ID, validUser.getEntityId())).andReturn(widgetStatistics);
+        expect(widgetService.getWidgetStatistics(WIDGET_ID, validUser.getId())).andReturn(widgetStatistics);
         replay(widgetService);
 
         String view = controller.viewWidget(model, WIDGET_ID, REFERRER_ID);
@@ -183,7 +171,7 @@
         int offset = 0;
         int pageSize = 10;
         SearchResult<Widget> searchResults = new SearchResult<Widget>(new ArrayList<Widget>(),0);
-        expect(widgetService.getAllWidgetStatistics(validUser.getEntityId())).andReturn(allWidgetStatisticsMap);
+        expect(widgetService.getAllWidgetStatistics(validUser.getId())).andReturn(allWidgetStatisticsMap);
         expect(tagService.getAllTags()).andReturn(new ArrayList<Tag>());
         expect(categoryService.getAll()).andReturn(new ArrayList<Category>());
         expect(widgetService.getWidgetsByCategory(categoryId, offset, pageSize)).andReturn(searchResults);
@@ -212,15 +200,15 @@
         int offset = 0;
         int pagesize = 10;
         int totalResults = 2;
-        Widget widget = new Widget();
-        widget.setEntityId(1L);
+        WidgetImpl widget = new WidgetImpl();
+        widget.setId(1L);
         List<Widget> widgets = new ArrayList<Widget>();
         widgets.add(widget);
         SearchResult<Widget> result = new SearchResult<Widget>(widgets, totalResults);
         result.setPageSize(pagesize);
 
         expect(widgetService.getPublishedWidgetsByFreeTextSearch(searchTerm, offset, pagesize)).andReturn(result);
-        expect(widgetService.getAllWidgetStatistics(validUser.getEntityId())).andReturn(allWidgetStatisticsMap);
+        expect(widgetService.getAllWidgetStatistics(validUser.getId())).andReturn(allWidgetStatisticsMap);
         replay(widgetService);
 
         String view = controller.viewSearchResult(model, REFERRER_ID, searchTerm, offset);
@@ -251,8 +239,8 @@
     public void doAddWidget() {
         final String widgetUrl = "http://example.com/newwidget.xml";
         final Model model = new ExtendedModelMap();
-        final Widget widget = new Widget();
-        widget.setEntityId(1L);
+        final WidgetImpl widget = new WidgetImpl();
+        widget.setId(1L);
         widget.setTitle("Widget title");
         widget.setUrl(widgetUrl);
         widget.setType("OpenSocial");
@@ -265,7 +253,7 @@
         String view = controller.viewAddWidgetResult(widget, errors, model,REFERRER_ID);
         verify(widgetService);
 
-        assertEquals("redirect:/app/store/widget/" + widget.getEntityId() +     "?referringPageId=" + REFERRER_ID, view);
+        assertEquals("redirect:/app/store/widget/" + widget.getId() +     "?referringPageId=" + REFERRER_ID, view);
         assertFalse("Valid widget data", errors.hasErrors());
     }
 
@@ -274,13 +262,13 @@
         final String widgetUrl = "http://example.com/existingwidget.xml";
         final Model model = new ExtendedModelMap();
 
-        final Widget existingWidget = new Widget();
-        existingWidget.setEntityId(123L);
+        final WidgetImpl existingWidget = new WidgetImpl();
+        existingWidget.setId(123L);
         existingWidget.setTitle("Widget title");
         existingWidget.setUrl(widgetUrl);
         existingWidget.setType("OpenSocial");
 
-        final Widget widget = new Widget();
+        final WidgetImpl widget = new WidgetImpl();
         widget.setTitle("Widget title");
         widget.setUrl(widgetUrl);
         widget.setType("OpenSocial");
@@ -298,7 +286,7 @@
 
     @Test
     public void doAddWidget_invalid() {
-        final Widget widget = new Widget();
+        final WidgetImpl widget = new WidgetImpl();
         widget.setTitle("Not enough data");
         final Model model = new ExtendedModelMap();
         final BindingResult errors = new BeanPropertyBindingResult(widget, "widget");
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/CategoryControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/CategoryControllerTest.java
index 2bb88a9..f41fbad 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/CategoryControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/CategoryControllerTest.java
@@ -18,6 +18,8 @@
 

 import org.apache.rave.portal.model.Category;

 import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.impl.CategoryImpl;

+import org.apache.rave.portal.model.impl.UserImpl;

 import org.apache.rave.portal.service.CategoryService;

 import org.apache.rave.portal.service.UserService;

 import org.apache.rave.portal.web.util.ModelKeys;

@@ -31,15 +33,8 @@
 import java.util.ArrayList;

 import java.util.List;

 

-import static junit.framework.Assert.assertEquals;

-import static junit.framework.Assert.assertFalse;

-import static junit.framework.Assert.assertSame;

-import static junit.framework.Assert.assertTrue;

-import static org.easymock.EasyMock.createMock;

-import static org.easymock.EasyMock.expect;

-import static org.easymock.EasyMock.expectLastCall;

-import static org.easymock.EasyMock.replay;

-import static org.easymock.EasyMock.verify;

+import static junit.framework.Assert.*;

+import static org.easymock.EasyMock.*;

 

 /**

  * Test for {@link CategoryController}

@@ -50,7 +45,7 @@
     private UserService userService;

     private CategoryService categoryService;

     private String validToken;

-    

+

     private static final String UPDATE = "update";

     private static final String DELETE = "delete";

     private static final String CREATE = "create";

@@ -64,23 +59,23 @@
         controller.setUserService(userService);

         controller.setCategoryService(categoryService);

     }

-    

+

     @Test

     public void getCategories_valid(){

         List<Category> categories = new ArrayList<Category>();

         expect(categoryService.getAll()).andReturn(categories);

         replay(categoryService);

-        

+

         Model model = new ExtendedModelMap();

-        

+

         String viewName = controller.getCategories("", model);

         verify(categoryService);

-        

+

         assertEquals(ViewNames.ADMIN_CATEGORIES, viewName);

         assertEquals(categories, model.asMap().get("categories"));

         assertFalse(model.containsAttribute("actionresult"));

         assertTrue(model.containsAttribute("category"));

-        assertEquals("Check that the category object available", new Category(), model.asMap().get("category"));

+        assertEquals("Check that the category object available", new CategoryImpl(), model.asMap().get("category"));

         assertTrue(model.containsAttribute("topnav"));

         assertTrue(model.containsAttribute("tabs"));

         assertTrue("verify tokencheck", model.asMap().containsKey(ModelKeys.TOKENCHECK));

@@ -102,7 +97,7 @@
         assertTrue(model.containsAttribute("actionresult"));

         assertEquals(UPDATE, model.asMap().get("actionresult"));

         assertTrue(model.containsAttribute("category"));

-        assertEquals("Check that the category object available", new Category(), model.asMap().get("category"));

+        assertEquals("Check that the category object available", new CategoryImpl(), model.asMap().get("category"));

         assertTrue(model.containsAttribute("topnav"));

         assertTrue(model.containsAttribute("tabs"));

     }

@@ -123,7 +118,7 @@
         assertTrue(model.containsAttribute("actionresult"));

         assertEquals(DELETE, model.asMap().get("actionresult"));

         assertTrue(model.containsAttribute("category"));

-        assertEquals("Check that the category object available", new Category(), model.asMap().get("category"));

+        assertEquals("Check that the category object available", new CategoryImpl(), model.asMap().get("category"));

         assertTrue(model.containsAttribute("topnav"));

         assertTrue(model.containsAttribute("tabs"));

     }

@@ -144,21 +139,21 @@
         assertTrue(model.containsAttribute("actionresult"));

         assertEquals(CREATE, model.asMap().get("actionresult"));

         assertTrue(model.containsAttribute("category"));

-        assertEquals("Check category object available", new Category(), model.asMap().get("category"));

+        assertEquals("Check category object available", new CategoryImpl(), model.asMap().get("category"));

         assertTrue(model.containsAttribute("topnav"));

         assertTrue(model.containsAttribute("tabs"));

     }

-    

+

     @Test

     public void createCategory_valid(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setText(categoryText);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

-        expect(categoryService.create(categoryText, user)).andReturn(new Category());

+        expect(categoryService.create(categoryText, user)).andReturn(new CategoryImpl());

         sessionStatus.setComplete();

         expectLastCall();

         replay(userService, categoryService,sessionStatus);

@@ -172,13 +167,13 @@
     public void createCategory_invalidToken(){

         Model model = new ExtendedModelMap();

         String invalidToken =  AdminControllerUtil.generateSessionToken();

-        User user = new User();

+        User user = new UserImpl();

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setText(categoryText);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

-        expect(categoryService.create(categoryText, user)).andReturn(new Category());

+        expect(categoryService.create(categoryText, user)).andReturn(new CategoryImpl());

         sessionStatus.setComplete();

         expectLastCall();

         replay(userService, categoryService,sessionStatus);

@@ -189,9 +184,9 @@
     @Test

     public void createCategory_invalidValidRequest_emptyText(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         String categoryText = "";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setText(categoryText);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

@@ -205,13 +200,13 @@
     @Test

     public void updateCategory_valid(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         expect(categoryService.get(id)).andReturn(category);

@@ -228,14 +223,14 @@
     @Test(expected = SecurityException.class)

     public void updateCategory_invalidToken(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

         String invalidToken = AdminControllerUtil.generateSessionToken();

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         expect(categoryService.get(id)).andReturn(category);

@@ -250,14 +245,14 @@
     @Test

     public void updateCategory_invalidValidRequest_emptyText(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

 

         long id = 1L;

         String categoryText = "";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         replay(userService);

@@ -271,12 +266,12 @@
     public void updateCategory_invalidValidRequest_nullUser(){

         Model model = new ExtendedModelMap();

         long id = 1L;

-        User user = new User();

+        User user = new UserImpl();

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         replay(userService);

@@ -289,13 +284,13 @@
     @Test

     public void updateCategory_invalidValidRequest_nullWidgetToUpdate(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         expect(categoryService.get(id)).andReturn(null).once();

@@ -309,13 +304,13 @@
     @Test

     public void deleteCategory_valid(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         expect(categoryService.get(id)).andReturn(category).anyTimes();

@@ -333,14 +328,14 @@
     @Test(expected = SecurityException.class)

     public void deleteCategory_invalidToken(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

         String invalidToken = AdminControllerUtil.generateSessionToken();

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         expect(categoryService.get(id)).andReturn(category);

@@ -356,14 +351,14 @@
     @Test

     public void deleteCategory_invalidValidRequest_emptyText(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

 

         long id = 1L;

         String categoryText = "";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         replay(userService);

@@ -377,12 +372,12 @@
     public void deleteCategory_invalidValidRequest_nullUser(){

         Model model = new ExtendedModelMap();

         long id = 1L;

-        User user = new User();

+        User user = new UserImpl();

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         replay(userService);

@@ -395,13 +390,13 @@
     @Test

     public void deleteCategory_invalidValidRequest_nullWidgetToDelete(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         expect(categoryService.get(id)).andReturn(null).once();

@@ -415,13 +410,13 @@
     @Test

     public void deleteCategory_invalidValidRequest_falseConfirmation(){

         Model model = new ExtendedModelMap();

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         SessionStatus sessionStatus = createMock(SessionStatus.class);

         expect(userService.getAuthenticatedUser()).andReturn(user).once();

         replay(userService);

@@ -433,14 +428,14 @@
 

     @Test

     public void editCategory_valid () {

-        User user = new User();

+        User user = new UserImpl();

         long id = 1L;

         String categoryText = "Social";

         Model model = new ExtendedModelMap();

-        Category category = new Category();

+        CategoryImpl category = new CategoryImpl();

         category.setCreatedUser(user);

         category.setText(categoryText);

-        category.setEntityId(id);

+        category.setId(id);

         expect(categoryService.get(id)).andReturn(category).once();

         replay(categoryService);

         String view = controller.editCategory(id, model);

diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java
index f28d266..d712eb9 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/PortalPreferenceControllerTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.web.controller.admin;
 
 import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.impl.PortalPreferenceImpl;
 import org.apache.rave.portal.service.PortalPreferenceService;
 import org.apache.rave.portal.web.model.PortalPreferenceForm;
 import org.apache.rave.portal.web.util.ModelKeys;
@@ -39,14 +40,8 @@
 import java.util.Map;
 import java.util.Set;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static junit.framework.Assert.*;
+import static org.easymock.EasyMock.*;
 
 /**
  * Test for {@link PortalPreferenceController}
@@ -168,7 +163,7 @@
     public void testUpdatePreferences_invalidPageSizeValue() {
         ModelMap model = new ExtendedModelMap();
         HashMap<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
-        PortalPreference pageSizePref = new PortalPreference(PortalPreferenceKeys.PAGE_SIZE, "invalid");
+        PortalPreference pageSizePref = new PortalPreferenceImpl(PortalPreferenceKeys.PAGE_SIZE, "invalid");
         preferenceMap.put(PortalPreferenceKeys.PAGE_SIZE, pageSizePref);
         PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
         final BindingResult errors = new BeanPropertyBindingResult(form, "form");
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/UserControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/UserControllerTest.java
index 7e57652..3e994a3 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/UserControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/UserControllerTest.java
@@ -19,26 +19,16 @@
 
 package org.apache.rave.portal.web.controller.admin;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.rave.portal.model.Authority;
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.AuthorityImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.service.AuthorityService;
 import org.apache.rave.portal.service.NewAccountService;
 import org.apache.rave.portal.service.PortalPreferenceService;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.apache.rave.portal.web.util.ModelKeys;
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.NewAccountValidator;
@@ -53,6 +43,12 @@
 import org.springframework.web.bind.support.SessionStatus;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.*;
+import static org.easymock.EasyMock.*;
+
 /**
  * Test for {@link UserController}
  */
@@ -108,7 +104,7 @@
     public void viewAdminUserDetail() throws Exception {
         Model model = new ExtendedModelMap();
         Long userid = 123L;
-        User user = new User(userid, "john.doe.sr");
+        User user = new UserImpl(userid, "john.doe.sr");
 
         expect(userService.getUserById(userid)).andReturn(user);
         replay(userService);
@@ -127,7 +123,7 @@
         ModelMap modelMap = new ExtendedModelMap();
         final Long userid = 123L;
         final String email = "john.doe.sr@example.net";
-        User user = new User(userid, "john.doe.sr");
+        UserImpl user = new UserImpl(userid, "john.doe.sr");
         user.setPassword("secrect");
         user.setConfirmPassword("secrect");
         user.setEmail(email);
@@ -152,7 +148,7 @@
     public void updateUserDetail_withErrors() {
         ModelMap modelMap = new ExtendedModelMap();
         Long userid = 123L;
-        User user = new User(userid, "john.doe.sr");
+        UserImpl user = new UserImpl(userid, "john.doe.sr");
         final BindingResult errors = new BeanPropertyBindingResult(user, "user");
 
         SessionStatus sessionStatus = createMock(SessionStatus.class);
@@ -167,7 +163,7 @@
     @Test(expected = SecurityException.class)
     public void updateUserDetail_wrongToken() {
         ModelMap modelMap = new ExtendedModelMap();
-        User user = new User(123L, "john.doe.sr");
+        UserImpl user = new UserImpl(123L, "john.doe.sr");
         final BindingResult errors = new BeanPropertyBindingResult(user, "user");
         SessionStatus sessionStatus = createMock(SessionStatus.class);
         sessionStatus.setComplete();
@@ -188,14 +184,14 @@
         ModelMap modelMap = new ExtendedModelMap();
         final Long userid = 123L;
         final String email = "john.doe.sr@example.net";
-        User user = new User(userid, "john.doe.sr");
+        User user = new UserImpl(userid, "john.doe.sr");
         user.setPassword("secrect");
         user.setConfirmPassword(user.getConfirmPassword());
         user.setEmail(email);
 
         SessionStatus sessionStatus = createMock(SessionStatus.class);
 
-        userService.deleteUser(user.getEntityId());
+        userService.deleteUser(user.getId());
         sessionStatus.setComplete();
         expectLastCall();
         replay(userService, sessionStatus);
@@ -210,7 +206,7 @@
     public void deleteUserDetail_noConfirmChecked() {
         ModelMap modelMap = new ExtendedModelMap();
         Long userid = 123L;
-        User user = new User(userid, "john.doe.sr");
+        User user = new UserImpl(userid, "john.doe.sr");
 
         SessionStatus sessionStatus = createMock(SessionStatus.class);
         replay(sessionStatus);
@@ -223,7 +219,7 @@
     @Test(expected = SecurityException.class)
     public void deleteUserDetail_wrongToken() {
         ModelMap modelMap = new ExtendedModelMap();
-        User user = new User(123L, "john.doe.sr");
+        User user = new UserImpl(123L, "john.doe.sr");
         SessionStatus sessionStatus = createMock(SessionStatus.class);
         sessionStatus.setComplete();
 
@@ -245,14 +241,14 @@
         final String viewName = controller.setUpForm(modelMap);
         assertEquals(ViewNames.ADMIN_NEW_ACCOUNT, viewName);
         assertTrue(modelMap.containsAttribute(TABS));
-        assertTrue(modelMap.get(ModelKeys.NEW_USER) instanceof User);
+        assertTrue(modelMap.get(ModelKeys.NEW_USER) instanceof UserImpl);
     }
 
     @Test
     public void create_ValidFormSubmitted() throws Exception {
         final Model model = createNiceMock(Model.class);
         final RedirectAttributes redirectAttributes = createNiceMock(RedirectAttributes.class);
-        final User User = new User();
+        final UserForm User = new UserForm();
         final BindingResult errors = new BeanPropertyBindingResult(User, ModelKeys.NEW_USER);
         final String username = "username";
         final String password = "password";
@@ -267,7 +263,7 @@
         expect(userService.getUserByUsername(username)).andReturn(null);
         expect(userService.getUserByEmail(email)).andReturn(null);
 
-        newAccountService.createNewAccount(User);
+        newAccountService.createNewAccount(isA(User.class));
 
         expectLastCall();
         replay(userService, model, newAccountService, redirectAttributes);
@@ -282,7 +278,7 @@
     public void create_EmptyForm() throws Exception {
         final Model model = createNiceMock(Model.class);
         final RedirectAttributes redirectAttributes = createNiceMock(RedirectAttributes.class);
-        final User User = new User();
+        final UserForm User = new UserForm();
         final BindingResult errors = new BeanPropertyBindingResult(User, ModelKeys.NEW_USER);
         final String username = "";
         final String password = "";
@@ -294,7 +290,7 @@
         User.setConfirmPassword(confirmPassword);
         User.setEmail(email);
 
-        newAccountService.createNewAccount(User);
+        newAccountService.createNewAccount(isA(User.class));
 
         replay(model);
 
@@ -341,8 +337,8 @@
 
 
     private static SearchResult<User> createSearchResultWithTwoUsers() {
-        User user1 = new User(123L, "john.doe.sr");
-        User user2 = new User(456L, "john.doe.jr");
+        UserImpl user1 = new UserImpl(123L, "john.doe.sr");
+        UserImpl user2 = new UserImpl(456L, "john.doe.jr");
         List<User> users = new ArrayList<User>();
         users.add(user1);
         users.add(user2);
@@ -352,9 +348,9 @@
 
     private static SearchResult<Authority> createSearchResultWithTwoAuthorities() {
         List<Authority> authorities = new ArrayList<Authority>();
-        Authority foo = new Authority();
+        Authority foo = new AuthorityImpl();
         foo.setAuthority("FOO");
-        Authority bar = new Authority();
+        Authority bar = new AuthorityImpl();
         bar.setAuthority("BAR");
         authorities.add(foo);
         authorities.add(bar);
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/WidgetControllerTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/WidgetControllerTest.java
index bd48a82..b26d3b9 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/WidgetControllerTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/admin/WidgetControllerTest.java
@@ -21,6 +21,8 @@
 
 import org.apache.rave.portal.model.Category;
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.CategoryImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.model.util.SearchResult;
 import org.apache.rave.portal.service.CategoryService;
 import org.apache.rave.portal.service.PortalPreferenceService;
@@ -31,7 +33,6 @@
 import org.apache.rave.portal.web.util.ViewNames;
 import org.apache.rave.portal.web.validator.UpdateWidgetValidator;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.springframework.ui.ExtendedModelMap;
 import org.springframework.ui.Model;
@@ -44,9 +45,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import static org.junit.Assert.*;
 import static org.easymock.EasyMock.*;
-import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
 
 /**
  * Test for {@link WidgetController}
@@ -81,8 +82,8 @@
         controller.setCategoryService(categoryService);
 
         categories = new ArrayList<Category>();
-        categories.add(new Category());
-        categories.add(new Category());
+        categories.add(new CategoryImpl());
+        categories.add(new CategoryImpl());
 
         webDataBinder = createMock(WebDataBinder.class);
         categoryEditor = new CategoryEditor(categoryService);
@@ -136,9 +137,9 @@
     @Test
     public void viewAdminWidgetDetail() throws Exception {
         Model model = new ExtendedModelMap();
-        Widget widget = new Widget();
+        WidgetImpl widget = new WidgetImpl();
         final long entityId = 123L;
-        widget.setEntityId(entityId);
+        widget.setId(entityId);
         widget.setTitle("My widget");
 
         expect(service.getWidget(entityId)).andReturn(widget);
@@ -157,8 +158,8 @@
     @Test
     public void updateWidget_valid() {
         final String widgetUrl = "http://example.com/widget";
-        Widget widget = new Widget(123L, widgetUrl);
-        widget.setTitle("Widget title");
+        WidgetImpl widget = new WidgetImpl(123L, widgetUrl);
+        widget.setTitle("WidgetImpl title");
         widget.setType("OpenSocial");
         widget.setDescription("Lorem ipsum");
         BindingResult errors = new BeanPropertyBindingResult(widget, "widget");
@@ -180,7 +181,7 @@
 
     @Test(expected = SecurityException.class)
     public void updateWidget_wrongToken() {
-        Widget widget = new Widget();
+        WidgetImpl widget = new WidgetImpl();
         BindingResult errors = new BeanPropertyBindingResult(widget, "widget");
         SessionStatus sessionStatus = createMock(SessionStatus.class);
         ModelMap modelMap = new ExtendedModelMap();
@@ -199,7 +200,7 @@
 
     @Test
     public void updateWidget_invalid() {
-        Widget widget = new Widget(123L, "http://broken/url");
+        WidgetImpl widget = new WidgetImpl(123L, "http://broken/url");
         BindingResult errors = new BeanPropertyBindingResult(widget, "widget");
         SessionStatus sessionStatus = createMock(SessionStatus.class);
         ModelMap modelMap = new ExtendedModelMap();
@@ -226,8 +227,8 @@
     private static SearchResult<Widget> populateWidgetSearchResult() {
         List<Widget> widgetList = new ArrayList<Widget>();
         for (int i = 0; i < DEFAULT_PAGESIZE; i++) {
-            Widget widget = new Widget();
-            widget.setTitle("Widget " + i);
+            WidgetImpl widget = new WidgetImpl();
+            widget.setTitle("WidgetImpl " + i);
             widgetList.add(widget);
         }
         return new SearchResult<Widget>(widgetList, 25);
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/CategoryEditorTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/CategoryEditorTest.java
index eaac4a4..b00edd1 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/CategoryEditorTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/controller/util/CategoryEditorTest.java
@@ -19,34 +19,33 @@
 package org.apache.rave.portal.web.controller.util;
 
 import org.apache.rave.portal.model.Category;
+import org.apache.rave.portal.model.impl.CategoryImpl;
 import org.apache.rave.portal.service.CategoryService;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.awt.*;
-
+import static org.easymock.EasyMock.*;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.junit.Assert.assertThat;
-import static org.easymock.EasyMock.*;
 
 public class CategoryEditorTest {
     private CategoryEditor categoryEditor;
     private CategoryService categoryService;
-    private final Long CATEGORY_ID = 333L;    
+    private final Long CATEGORY_ID = 333L;
     private final String CATEGORY_TEXT = "category1";
     private Category validCategory;
-         
+
     @Before
     public void setUp() {
         categoryService = createMock(CategoryService.class);
         categoryEditor = new CategoryEditor(categoryService);
 
-        validCategory = new Category();
-        validCategory.setEntityId(CATEGORY_ID);
+        validCategory = new CategoryImpl();
+        validCategory.setId(CATEGORY_ID);
         validCategory.setText(CATEGORY_TEXT);
     }
-    
+
     @Test
     public void setAsText() {
         expect(categoryService.get(CATEGORY_ID)).andReturn(validCategory);
@@ -54,16 +53,16 @@
         categoryEditor.setAsText(String.valueOf(CATEGORY_ID));
         verify(categoryService);
     }
-    
+
     @Test
     public void getAsText_validCategory() {
-        categoryEditor.setValue(validCategory);        
-        assertThat(categoryEditor.getAsText(), is(validCategory.getEntityId().toString()));  
+        categoryEditor.setValue(validCategory);
+        assertThat(categoryEditor.getAsText(), is(validCategory.getId().toString()));
     }
 
     @Test
     public void getAsText_nullCategory() {
         categoryEditor.setValue(null);
         assertThat(categoryEditor.getAsText(), is(nullValue(String.class)));
-    }    
+    }
 }
\ No newline at end of file
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java
index 8636e02..5dc479e 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/model/PortalPreferenceFormTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.web.model;
 
 import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.impl.PortalPreferenceImpl;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -37,11 +38,11 @@
 
     @Before
     public void setUp() throws Exception {
-        PortalPreference titlePref = new PortalPreference(TITLE_SUFFIX, "Test portal");
+        PortalPreference titlePref = new PortalPreferenceImpl(TITLE_SUFFIX, "Test portal");
         preferenceMap.put(TITLE_SUFFIX, titlePref);
-        PortalPreference pageSizePref = new PortalPreference(PAGE_SIZE, "20");
+        PortalPreference pageSizePref = new PortalPreferenceImpl(PAGE_SIZE, "20");
         preferenceMap.put(PAGE_SIZE, pageSizePref);
-        PortalPreference javaScriptDebugMode = new PortalPreference(JAVASCRIPT_DEBUG_MODE, "0");
+        PortalPreference javaScriptDebugMode = new PortalPreferenceImpl(JAVASCRIPT_DEBUG_MODE, "0");
         preferenceMap.put(JAVASCRIPT_DEBUG_MODE, javaScriptDebugMode);
     }
 
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapperTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapperTest.java
index 9971a5d..04ac829 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapperTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/security/LdapUserDetailsContextMapperTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.web.security;
 
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.NewAccountService;
 import org.apache.rave.portal.service.UserService;
 import org.junit.Before;
@@ -31,14 +32,8 @@
 
 import java.util.Collections;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static junit.framework.Assert.*;
+import static org.easymock.EasyMock.*;
 
 /**
  * Test class for {@link LdapUserDetailsContextMapper}
@@ -64,7 +59,7 @@
         DirContextOperations ctx = createMock(DirContextOperations.class);
 
         final String username = "johnldap";
-        User user = new User(123L, username);
+        User user = new UserImpl(123L, username);
 
         expect(userService.getUserByUsername(username)).andReturn(null).once();
         expect(ctx.attributeExists(MAIL_ATTRIBUTE_NAME)).andReturn(true);
@@ -88,7 +83,7 @@
         DirContextOperations ctx = createMock(DirContextOperations.class);
 
         final String username = "johnldap";
-        User user = new User(123L, username);
+        User user = new UserImpl(123L, username);
 
         expect(userService.getUserByUsername(username)).andReturn(null).once();
         expect(ctx.attributeExists(MAIL_ATTRIBUTE_NAME)).andReturn(true);
@@ -157,7 +152,7 @@
         DirContextOperations ctx = createMock(DirContextOperations.class);
 
         final String username = "johnldap";
-        User user = new User(123L, username);
+        User user = new UserImpl(123L, username);
 
         expect(userService.getUserByUsername(username)).andReturn(user);
         expectLastCall();
@@ -173,7 +168,7 @@
 
     @Test
     public void testMapUserToContext() throws Exception {
-        User user = new User();
+        User user = new UserImpl();
         DirContextAdapter adapter = new DirContextAdapter();
 
         contextMapper.mapUserToContext(user, adapter);
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/RegionWidgetTagTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/RegionWidgetTagTest.java
index ce98a3c..1790e7c 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/RegionWidgetTagTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/tag/RegionWidgetTagTest.java
@@ -19,10 +19,11 @@
 
 package org.apache.rave.portal.web.tag;
 
-import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.rave.portal.model.Region;
 import org.apache.rave.portal.model.RegionWidget;
-import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.RegionImpl;
+import org.apache.rave.portal.model.impl.RegionWidgetImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.web.renderer.RenderScope;
 import org.apache.rave.portal.web.renderer.RenderService;
 import org.apache.rave.portal.web.renderer.ScriptLocation;
@@ -82,8 +83,8 @@
 
     @Test
     public void doStartTag_valid() throws IOException, JspException {
-        RegionWidget regionWidget = new RegionWidget();
-        Widget widget = new Widget();
+        RegionWidget regionWidget = new RegionWidgetImpl();
+        WidgetImpl widget = new WidgetImpl();
         regionWidget.setWidget(widget);
         widget.setType(WIDGET_TYPE);
 
@@ -118,8 +119,8 @@
     @Test(expected = JspException.class)
     public void doStartTag_IOException() throws JspException, IOException {
 
-        RegionWidget regionWidget = new RegionWidget();
-        Widget widget = new Widget();
+        RegionWidget regionWidget = new RegionWidgetImpl();
+        WidgetImpl widget = new WidgetImpl();
         regionWidget.setWidget(widget);
         widget.setType("INVALID");
 
@@ -144,9 +145,9 @@
     public void doStartTag_unsupportedWidget() throws JspException {
         replay(pageContext);
 
-        RegionWidget regionWidget = new RegionWidget();
-        Region region = new Region(25L);
-        Widget widget = new Widget();
+        RegionWidget regionWidget = new RegionWidgetImpl();
+        Region region = new RegionImpl(25L);
+        WidgetImpl widget = new WidgetImpl();
         regionWidget.setWidget(widget);
         regionWidget.setRegion(region);
         widget.setType("INVALID");
@@ -165,16 +166,16 @@
     public void doStartTag_disabledWidget() throws IOException, JspException {
         final String DISABLED_WIDGET_MESSAGE = "THIS IS DISABLED";
 
-        Widget widget = new Widget();
-        widget.setEntityId(8L);
+        WidgetImpl widget = new WidgetImpl();
+        widget.setId(8L);
         widget.setType(WIDGET_TYPE);
         widget.setDisableRendering(true);
         widget.setDisableRenderingMessage(DISABLED_WIDGET_MESSAGE);
 
-        RegionWidget regionWidget = new RegionWidget();
-        regionWidget.setEntityId(99L);
+        RegionWidget regionWidget = new RegionWidgetImpl();
+        regionWidget.setId(99L);
         regionWidget.setWidget(widget);
-        regionWidget.setRegion(new Region(2L));
+        regionWidget.setRegion(new RegionImpl(2L));
 
         Set<String> strings = new HashSet<String>();
         strings.add(WIDGET_TYPE);
@@ -196,7 +197,7 @@
 
     @Test
     public void getRegionWidget() throws IOException, JspException {
-        RegionWidget regionWidget = new RegionWidget();
+        RegionWidget regionWidget = new RegionWidgetImpl();
         tag.setRegionWidget(regionWidget);
         assertThat(tag.getRegionWidget(), sameInstance(regionWidget));
     }
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewAccountValidatorTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewAccountValidatorTest.java
index bef29bd..bb6e683 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewAccountValidatorTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewAccountValidatorTest.java
@@ -19,21 +19,17 @@
 
 package org.apache.rave.portal.web.validator;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.service.UserService;
+import org.apache.rave.portal.web.model.UserForm;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.validation.BindException;
 import org.springframework.validation.Errors;
 
+import static junit.framework.Assert.*;
+import static org.easymock.EasyMock.*;
+
 /**
  * Test class for {@link NewAccountValidator}
  */
@@ -54,12 +50,12 @@
     @Test
     public void testSupports() throws Exception {
         assertTrue("Can validate org.apache.rave.portal.model.User",
-                newAccountValidator.supports(User.class));
+                newAccountValidator.supports(UserForm.class));
     }
 
     @Test
     public void testValidate() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         user.setUsername(VALID_NAME);
         user.setPassword(VALID_PASSWORD);
         user.setConfirmPassword(VALID_PASSWORD);
@@ -78,7 +74,7 @@
 
     @Test
     public void testValidationFailsOnEmptyUser() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         Errors errors = new BindException(user, NEW_USER);
         expect(mockUserService.getUserByUsername("")).andReturn(null);
         replay(mockUserService);
@@ -96,7 +92,7 @@
 
     @Test
     public void testValidationFailsOnExistingUser() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         user.setUsername("ExistingUser");
         user.setPassword(VALID_PASSWORD);
         user.setConfirmPassword(VALID_PASSWORD);
@@ -117,7 +113,7 @@
 
     @Test
     public void testValidationFailsOnExistingEmail() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         user.setUsername(VALID_NAME);
         user.setPassword(VALID_PASSWORD);
         user.setConfirmPassword(VALID_PASSWORD);
@@ -139,7 +135,7 @@
 
     @Test
     public void testValidationFailsOnShortUserName() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         user.setUsername("A");
         user.setPassword(VALID_PASSWORD);
         user.setConfirmPassword(VALID_PASSWORD);
@@ -158,7 +154,7 @@
 
     @Test
     public void testValidationFailsOnIllegalUsername() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         final String badUsername = "x'; DROP TABLE members; --";
         user.setUsername(badUsername);
         user.setPassword(VALID_PASSWORD);
@@ -178,7 +174,7 @@
 
     @Test
     public void testValidationFailsOnShortPassword() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         user.setUsername(VALID_NAME);
         user.setPassword("123");
         user.setConfirmPassword("123");
@@ -197,7 +193,7 @@
 
     @Test
     public void testValidationFailsOnNonMatchingPassword() throws Exception {
-        User user = new User();
+        UserForm user = new UserForm();
         user.setUsername(VALID_NAME);
         user.setPassword(VALID_PASSWORD);
         user.setConfirmPassword("doesnotmatch");
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewWidgetValidatorTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewWidgetValidatorTest.java
index 6efdc16..bef5421 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewWidgetValidatorTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/NewWidgetValidatorTest.java
@@ -20,19 +20,15 @@
 package org.apache.rave.portal.web.validator;
 
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.service.WidgetService;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.validation.BindException;
 import org.springframework.validation.Errors;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static junit.framework.Assert.*;
+import static org.easymock.EasyMock.*;
 
 /**
  * Test class for {@link NewWidgetValidator}
@@ -50,7 +46,7 @@
 
     @Test
     public void testValidateValidFormData() throws Exception {
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         widget.setTitle(VALID_TITLE);
         widget.setUrl(VALID_URL);
         widget.setType(VALID_TYPE);
@@ -67,7 +63,7 @@
 
     @Test
     public void testValidationFailsOnEmptyValues() {
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         Errors errors = new BindException(widget, WIDGET);
 
         widgetValidator.validate(widget, errors);
@@ -79,14 +75,14 @@
     public void testValidationFailsOnDuplicateUrl() {
         final String existingUrl = "http://example.com/existing_widget.xml";
 
-        Widget widget = new Widget();
-        widget.setEntityId(123L);
+        WidgetImpl widget = new WidgetImpl();
+        widget.setId(123L);
         widget.setTitle(VALID_TITLE);
         widget.setType(VALID_TYPE);
         widget.setDescription(VALID_DESCRIPTION);
         widget.setUrl(existingUrl);
 
-        Widget newWidget = new Widget();
+        Widget newWidget = new WidgetImpl();
         newWidget.setTitle(VALID_TITLE);
         newWidget.setType(VALID_TYPE);
         newWidget.setDescription(VALID_DESCRIPTION);
@@ -104,7 +100,7 @@
 
     @Test
     public void testValidationFailsOnInvalidUrl() {
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         widget.setTitle(VALID_TITLE);
         widget.setType(VALID_TYPE);
         widget.setUrl("http:/this.is/invalid?url=true&reject=true");
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java
index 52715ed..de4f96e 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/PortalPreferenceFormValidatorTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.portal.web.validator;
 
 import org.apache.rave.portal.model.PortalPreference;
+import org.apache.rave.portal.model.impl.PortalPreferenceImpl;
 import org.apache.rave.portal.web.model.PortalPreferenceForm;
 import org.junit.Before;
 import org.junit.Test;
@@ -29,10 +30,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.*;
 import static org.apache.rave.portal.web.util.PortalPreferenceKeys.PAGE_SIZE;
 import static org.apache.rave.portal.web.util.PortalPreferenceKeys.TITLE_SUFFIX;
 
@@ -55,8 +53,8 @@
     @Test
     public void testValidate_Valid() throws Exception {
         Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
-        preferenceMap.put(TITLE_SUFFIX, new PortalPreference(TITLE_SUFFIX, "- Rave unit test"));
-        preferenceMap.put(PAGE_SIZE, new PortalPreference(PAGE_SIZE, "10"));
+        preferenceMap.put(TITLE_SUFFIX, new PortalPreferenceImpl(TITLE_SUFFIX, "- Rave unit test"));
+        preferenceMap.put(PAGE_SIZE, new PortalPreferenceImpl(PAGE_SIZE, "10"));
         PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
         Errors errors = new BindException(form, "form");
         validator.validate(form, errors);
@@ -80,7 +78,7 @@
     @Test
     public void testValidate_InvalidPageSize() throws Exception {
         Map<String, PortalPreference> preferenceMap = new HashMap<String, PortalPreference>();
-        preferenceMap.put(PAGE_SIZE, new PortalPreference(PAGE_SIZE, "10.5"));
+        preferenceMap.put(PAGE_SIZE, new PortalPreferenceImpl(PAGE_SIZE, "10.5"));
         PortalPreferenceForm form = new PortalPreferenceForm(preferenceMap);
         Errors errors = new BindException(form, "form");
         validator.validate(form, errors);
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UpdateWidgetValidatorTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UpdateWidgetValidatorTest.java
index 5332e31..03aea3f 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UpdateWidgetValidatorTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UpdateWidgetValidatorTest.java
@@ -20,19 +20,15 @@
 package org.apache.rave.portal.web.validator;
 
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.service.WidgetService;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.validation.BindException;
 import org.springframework.validation.Errors;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static junit.framework.Assert.*;
+import static org.easymock.EasyMock.*;
 
 /**
  * Test class for {@link org.apache.rave.portal.web.validator.UpdateWidgetValidator}
@@ -50,8 +46,8 @@
 
     @Test
     public void testValidateValidFormData() throws Exception {
-        Widget widget = new Widget();
-        widget.setEntityId(123L);
+        WidgetImpl widget = new WidgetImpl();
+        widget.setId(123L);
         widget.setTitle(VALID_TITLE);
         widget.setUrl(VALID_URL);
         widget.setType(VALID_TYPE);
@@ -68,7 +64,7 @@
 
     @Test
     public void testValidationFailsOnEmptyValues() {
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         Errors errors = new BindException(widget, WIDGET);
 
         widgetValidator.validate(widget, errors);
@@ -80,14 +76,14 @@
     public void testValidationFailsOnDuplicateUrl() {
         final String existingUrl = "http://example.com/existing_widget.xml";
 
-        Widget widget = new Widget();
-        widget.setEntityId(123L);
+        WidgetImpl widget = new WidgetImpl();
+        widget.setId(123L);
         widget.setTitle(VALID_TITLE);
         widget.setType(VALID_TYPE);
         widget.setDescription(VALID_DESCRIPTION);
         widget.setUrl(existingUrl);
 
-        Widget newWidget = new Widget();
+        Widget newWidget = new WidgetImpl();
         newWidget.setTitle(VALID_TITLE);
         newWidget.setType(VALID_TYPE);
         newWidget.setDescription(VALID_DESCRIPTION);
@@ -105,7 +101,7 @@
 
     @Test
     public void testValidationFailsOnInvalidUrl() {
-        Widget widget = new Widget();
+        Widget widget = new WidgetImpl();
         widget.setTitle(VALID_TITLE);
         widget.setType(VALID_TYPE);
         widget.setDescription(VALID_DESCRIPTION);
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UserProfileValidatorTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UserProfileValidatorTest.java
index 9c8480a..40fa3dd 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UserProfileValidatorTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/UserProfileValidatorTest.java
@@ -20,15 +20,14 @@
 package org.apache.rave.portal.web.validator;
 
 import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.model.impl.UserImpl;
 import org.apache.rave.portal.service.UserService;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.validation.BindException;
 import org.springframework.validation.Errors;
 
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.*;
 import static org.easymock.EasyMock.createMock;
 
 /**
@@ -46,12 +45,12 @@
 
     @Test
     public void testSupports() throws Exception {
-        assertTrue("Can validate org.apache.rave.portal.model.User", validator.supports(User.class));
+        assertTrue("Can validate org.apache.rave.portal.model.User", validator.supports(UserImpl.class));
     }
 
     @Test
     public void testValidate() throws Exception {
-        User user = new User();
+        User user = new UserImpl();
         user.setUsername(VALID_NAME);
         user.setPassword(VALID_PASSWORD);
         user.setConfirmPassword(VALID_PASSWORD);
@@ -65,7 +64,7 @@
 
     @Test
     public void testValidateFailsOnEmptyPassword() throws Exception {
-        User user = new User();
+        User user = new UserImpl();
         user.setUsername(VALID_NAME);
         user.setEmail(VALID_EMAIL);
 
@@ -79,7 +78,7 @@
 
     @Test
     public void testValidateFailsOnShortPassword() throws Exception {
-        User user = new User();
+        User user = new UserImpl();
         user.setUsername(VALID_NAME);
         user.setPassword("123");
         user.setPassword("123");
@@ -94,7 +93,7 @@
 
     @Test
     public void testValidateFailsOnPasswordMismatch() throws Exception {
-        User user = new User();
+        User user = new UserImpl();
         user.setUsername(VALID_NAME);
         user.setPassword(VALID_PASSWORD);
         user.setConfirmPassword("DoesNotMatch");
diff --git a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/WidgetValidatorTest.java b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/WidgetValidatorTest.java
index 3c6d393..5251f49 100644
--- a/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/WidgetValidatorTest.java
+++ b/rave-components/rave-web/src/test/java/org/apache/rave/portal/web/validator/WidgetValidatorTest.java
@@ -19,16 +19,17 @@
 
 package org.apache.rave.portal.web.validator;
 
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
 import org.apache.commons.validator.routines.RegexValidator;
 import org.apache.commons.validator.routines.UrlValidator;
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.validation.Errors;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 /**
  * Test for {@link WidgetValidator}
  */
@@ -43,7 +44,7 @@
 
     @Test
     public void testSupports() throws Exception {
-        assertTrue("Supports org.apache.rave.portal.model.Widget", widgetValidator.supports(Widget.class));
+        assertTrue("Supports org.apache.rave.portal.model.Widget", widgetValidator.supports(WidgetImpl.class));
     }
 
   /*
diff --git a/rave-demo-gadgets/pom.xml b/rave-demo-gadgets/pom.xml
index c9d24c1..2000045 100644
--- a/rave-demo-gadgets/pom.xml
+++ b/rave-demo-gadgets/pom.xml
@@ -50,4 +50,4 @@
         </plugins>
 
     </build>
-</project>
\ No newline at end of file
+</project>
diff --git a/rave-portal-dependencies/pom.xml b/rave-portal-dependencies/pom.xml
index da447d6..2689b10 100644
--- a/rave-portal-dependencies/pom.xml
+++ b/rave-portal-dependencies/pom.xml
@@ -45,6 +45,10 @@
         </dependency>
         <dependency>
             <groupId>org.apache.rave</groupId>
+            <artifactId>rave-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.rave</groupId>
             <artifactId>rave-web</artifactId>
         </dependency>
         <dependency>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/applicationContext.xml b/rave-portal-resources/src/main/webapp/WEB-INF/applicationContext.xml
index 857f485..ad190a5 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/applicationContext.xml
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/applicationContext.xml
@@ -25,6 +25,7 @@
                            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
 
     <import resource="classpath*:org/apache/rave/core-applicationContext.xml"/>
+    <import resource="classpath*:org/apache/rave/jpa-applicationContext.xml"/>
     <import resource="classpath*:org/apache/rave/web-applicationContext.xml"/>
     <import resource="classpath*:org/apache/rave/opensocial-provider-applicationContext.xml"/>
     <import resource="classpath*:org/apache/rave/w3c-provider-applicationContext.xml"/>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/db/initial_data.sql b/rave-portal-resources/src/main/webapp/WEB-INF/db/initial_data.sql
index 837274d..1504128 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/db/initial_data.sql
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/db/initial_data.sql
@@ -190,17 +190,17 @@
 -- user association data --
 set @next_person_association = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @person_association_seq);
 INSERT INTO person_association(entity_id, follower_id, followed_id)
-VALUES (@next_person_association, @person_id_1, @person_id_2);
+VALUES (@next_person_association, @user_id_1, @user_id_2);
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @person_association_seq;
 
 set @next_person_association = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @person_association_seq);
 INSERT INTO person_association(entity_id, follower_id, followed_id)
-VALUES (@next_person_association, @person_id_1, @person_id_3);
+VALUES (@next_person_association, @user_id_1, @user_id_3);
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @person_association_seq;
 
 set @next_person_association = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @person_association_seq);
 INSERT INTO person_association(entity_id, follower_id, followed_id)
-VALUES (@next_person_association, @person_id_2, @person_id_4);
+VALUES (@next_person_association, @user_id_2, @user_id_4);
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @person_association_seq;
 
 -- end user association data --
@@ -1054,21 +1054,21 @@
 set @next_portal_preference_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @portal_preference_seq);
 INSERT INTO portal_preference (entity_id, preference_key)
 values (@next_portal_preference_id, 'titleSuffix');
-INSERT INTO portalpreference_values
+INSERT INTO JPAPORTALPREFERENCE_VALUES
 values (@next_portal_preference_id, ' - Rave');
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @portal_preference_seq;
 
 set @next_portal_preference_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @portal_preference_seq);
 INSERT INTO portal_preference (entity_id, preference_key)
 values (@next_portal_preference_id, 'pageSize');
-INSERT INTO portalpreference_values
+INSERT INTO JPAPORTALPREFERENCE_VALUES
 values (@next_portal_preference_id, '10');
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @portal_preference_seq;
 
 set @next_portal_preference_id = (SELECT seq_count FROM RAVE_PORTAL_SEQUENCES WHERE seq_name = @portal_preference_seq);
 INSERT INTO portal_preference (entity_id, preference_key)
 values (@next_portal_preference_id, 'javaScriptDebugMode');
-INSERT INTO portalpreference_values
+INSERT INTO JPAPORTALPREFERENCE_VALUES
 values (@next_portal_preference_id, '1');
 UPDATE RAVE_PORTAL_SEQUENCES SET seq_count = (seq_count + 1) WHERE seq_name = @portal_preference_seq;
 -- end portal preferences
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml b/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml
index 76e14c2..07e4bfc 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/dispatcher-servlet.xml
@@ -37,7 +37,35 @@
     <context:component-scan base-package="org.apache.rave.portal.web.api"/>
 
     <!-- Configures the @Controller programming model -->
-    <mvc:annotation-driven/>
+    <mvc:annotation-driven>
+        <mvc:message-converters>
+            <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
+                <property name="supportedMediaTypes">
+                    <list>
+                        <bean class="org.springframework.http.MediaType">
+                            <constructor-arg index="0" value="text"/>
+                            <constructor-arg index="1" value="plain"/>
+                            <constructor-arg index="2" value="UTF-8"/>
+                        </bean>
+                        <bean class="org.springframework.http.MediaType">
+                            <constructor-arg index="0" value="text"/>
+                            <constructor-arg index="1" value="javascript"/>
+                            <constructor-arg index="2" value="UTF-8"/>
+                        </bean>
+                    </list>
+                </property>
+            </bean>
+            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
+                <property name="objectMapper">
+                    <bean class="org.apache.rave.portal.web.model.MaterializedBeanObjectMapperFactory"/>
+                </property>
+            </bean>
+            <bean primary="true" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
+                <property name="marshaller" ref="xmlMarshaller"/>
+                <property name="unmarshaller" ref="xmlMarshaller"/>
+            </bean>
+        </mvc:message-converters>
+    </mvc:annotation-driven>
     <mvc:interceptors>
         <bean class="org.apache.rave.portal.web.interceptors.CommonModelHandlerInterceptor"/>
         <!--
@@ -49,7 +77,7 @@
             can be used if you need to get more detailed information about
             the device such as manufacturer, model, screen size, etc.
         -->
-        <bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor" />
+        <bean class="org.springframework.mobile.device.DeviceResolverHandlerInterceptor"/>
     </mvc:interceptors>
 
     <!-- Forwards requests to the "/" resource to the "page" view -->
@@ -61,9 +89,13 @@
         <property name="suffix" value=".jsp"/>
     </bean>
 
-    <oxm:jaxb2-marshaller id="marshaller">
-        <oxm:class-to-be-bound name="org.apache.rave.portal.model.Page"/>
-        <oxm:class-to-be-bound name="org.apache.rave.portal.model.RegionWidgetPreference"/>
+    <oxm:jaxb2-marshaller id="xmlMarshaller">
+        <oxm:class-to-be-bound name="org.apache.rave.portal.model.JpaUser"/>
+        <oxm:class-to-be-bound name="org.apache.rave.portal.model.JpaPage"/>
+        <oxm:class-to-be-bound name="org.apache.rave.portal.model.JpaRegion"/>
+        <oxm:class-to-be-bound name="org.apache.rave.portal.model.JpaRegionWidget"/>
+        <oxm:class-to-be-bound name="org.apache.rave.portal.model.JpaRegionWidgetPreference"/>
+        <oxm:class-to-be-bound name="org.apache.rave.portal.model.JpaWidget"/>
         <oxm:class-to-be-bound name="org.apache.rave.portal.web.model.RegionWidgetPreferenceListWrapper"/>
     </oxm:jaxb2-marshaller>
 
@@ -86,8 +118,8 @@
                         </list>
                     </property>
                 </bean>
-                <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"
-                      p:marshaller-ref="marshaller" p:unmarshaller-ref="marshaller"/>
+             <!--   <bean primary="true" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"
+                      p:marshaller-ref="xmlMarshaller" p:unmarshaller-ref="xmlMarshaller"/>-->
             </list>
         </property>
     </bean>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp
index 5de0674..47e0e8f 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/preferences.jsp
@@ -39,7 +39,7 @@
             <h2><fmt:message key="admin.preferences.shorttitle"/></h2>
 
             <spring:url value="/app/admin/preferencedetail/edit" var="detaillink"/>
-            <%--@elvariable id="preferenceMap" type="java.util.Map<java.lang.String, org.apache.rave.portal.model.PortalPreference>"--%>
+                <%--@elvariable id="preferenceMap" type="java.util.Map<java.lang.String, org.apache.rave.portal.model.JpaPortalPreference>"--%>
             <c:choose>
                 <c:when test="${fn:length(preferenceMap) eq 0}">
                     <a class="btn btn-primary" href="<c:out value="${detaillink}"/>"><fmt:message key="admin.preferences.edit"/></a>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/userdetail.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/userdetail.jsp
index 3bcc3e5..ef83bda 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/userdetail.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/userdetail.jsp
@@ -70,6 +70,7 @@
                         <fieldset>
                             <legend><fmt:message key="admin.userdetail.editdata"/></legend>
                             <input type="hidden" name="token" value="<c:out value="${tokencheck}"/>"/>
+                            <form:hidden path="username" />
                             <div class="control-group">
                                 <label class="control-label" for="email"><fmt:message key="page.general.email"/></label>
                                 <div class="controls"><spring:bind path="email">
@@ -112,7 +113,7 @@
                         </fieldset>
                         <fieldset>
                             <span class="label"><fmt:message key="admin.userdata.authorities"/></span>
-                                <%--@elvariable id="authorities" type="org.apache.rave.portal.model.util.SearchResult<org.apache.rave.portal.model.Authority>"--%>
+                                <%--@elvariable id="authorities" type="org.apache.rave.portal.model.util.SearchResult<org.apache.rave.portal.model.JpaAuthority>"--%>
                             <ul class="checkboxlist">
                                 <form:checkboxes path="authorities" items="${authorities.resultSet}" itemLabel="authority" itemValue="authority" element="li"/>
                             </ul>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/users.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/users.jsp
index 587cc70..91249af 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/users.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/users.jsp
@@ -19,7 +19,7 @@
 <%@ page language="java" trimDirectiveWhitespaces="true" %>
 <%@ include file="/WEB-INF/jsp/includes/taglibs.jsp" %>
 <fmt:setBundle basename="messages"/>
-<%--@elvariable id="searchResult" type="org.apache.rave.portal.model.util.SearchResult<org.apache.rave.portal.model.User>"--%>
+<%--@elvariable id="searchResult" type="org.apache.rave.portal.model.util.SearchResult<org.apache.rave.portal.model.JpaUser>"--%>
 
 <fmt:message key="${pageTitleKey}" var="pagetitle"/>
 <rave:navbar pageTitle="${pagetitle}"/>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/widgets.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/widgets.jsp
index 3a1a064..aacfc7e 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/widgets.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/admin/widgets.jsp
@@ -19,7 +19,7 @@
 <%@ page language="java" trimDirectiveWhitespaces="true" %>
 <%@ include file="/WEB-INF/jsp/includes/taglibs.jsp" %>
 <fmt:setBundle basename="messages"/>
-<%--@elvariable id="searchResult" type="org.apache.rave.portal.model.util.SearchResult<org.apache.rave.portal.model.Widget>"--%>
+<%--@elvariable id="searchResult" type="org.apache.rave.portal.model.util.SearchResult<org.apache.rave.portal.model.JpaWidget>"--%>
 <fmt:message key="${pageTitleKey}" var="pagetitle"/>
 <rave:navbar pageTitle="${pagetitle}"/>
 <div class="container-fluid">
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/page.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/page.jsp
index f4b1c16..fa9d2b1 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/page.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/page.jsp
@@ -22,7 +22,7 @@
 <fmt:setBundle basename="messages"/>
 <jsp:useBean id="pages" type="java.util.List<org.apache.rave.portal.model.Page>" scope="request"/>
 <jsp:useBean id="pageUser" type="org.apache.rave.portal.model.PageUser" scope="request"/>
-<jsp:useBean id="pageLayouts" type="java.util.List<org.apache.rave.portal.model.PageLayout>" scope="request"/>
+<jsp:useBean id="pageLayouts" type="java.util.List<org.apache.rave.portal.model.JpaPageLayout>" scope="request"/>
 <%--@elvariable id="page" type="org.apache.rave.portal.model.Page"--%>
 <sec:authentication property="principal.username" var="principleUsername" scope="request"/>
 <sec:authentication property="principal.displayName" var="displayName" scope="request"/>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp
index f9a832e..e3a81ae 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/personProfile.jsp
@@ -24,7 +24,7 @@
 <%@ page errorPage="/WEB-INF/jsp/views/error.jsp" %>
 <%@ include file="/WEB-INF/jsp/includes/taglibs.jsp" %>
 <fmt:setBundle basename="messages"/>
-<jsp:useBean id="userProfile" type="org.apache.rave.portal.model.User" scope="request"/>
+<jsp:useBean id="userProfile" type="org.apache.rave.portal.model.JpaUser" scope="request"/>
 
 <!-- get the display name of user -->
 <fmt:message key="page.personProfile.title" var="pageTitle">
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/store.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/store.jsp
index 14a2f1a..1bd6d12 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/store.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/store.jsp
@@ -77,7 +77,7 @@
 
                 </c:if>
                 <ul class="storeItems">
-                        <%--@elvariable id="widget" type="org.apache.rave.portal.model.Widget"--%>
+                        <%--@elvariable id="widget" type="org.apache.rave.portal.model.JpaWidget"--%>
                     <c:forEach var="widget" items="${widgets.resultSet}">
                         <%--@elvariable id="widgetsStatistics" type="org.apache.rave.portal.model.util.WidgetStatistics"--%>
                         <c:set var="widgetStatistics" value="${widgetsStatistics[widget.entityId]}"/>
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/userProfile.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/userProfile.jsp
index 6ce07b9..792985c 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/userProfile.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/userProfile.jsp
@@ -19,7 +19,7 @@
 <%@ page language="java" trimDirectiveWhitespaces="true" %>
 <%@ include file="/WEB-INF/jsp/includes/taglibs.jsp" %>
 <fmt:setBundle basename="messages"/>
-<jsp:useBean id="userProfile" type="org.apache.rave.portal.model.User" scope="request"/>
+<jsp:useBean id="userProfile" type="org.apache.rave.portal.model.JpaUser" scope="request"/>
 <div id="content">
     <h1>${pagetitle}</h1>
     <form:form id="userProfileForm" commandName="userProfile" action="updateUserProfile" method="POST">
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/widget.jsp b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/widget.jsp
index b0e4f99..9e956a7 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/widget.jsp
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/jsp/views/widget.jsp
@@ -201,7 +201,7 @@
                                         </span>
                                         <c:if test="${userProfile.entityId eq comment.user.entityId}">
                                             <button id="comment-delete-${comment.entityId}" class="btn btn-danger btn-mini commentDeleteButton"
-                                                    value="Delete" title="Delete comment" data-widget id="<c:out value="${comment.widgetId}"/>">
+                                                    value="Delete" title="Delete comment" data-widgetid="<c:out value="${comment.widgetId}"/>">
                                                 <i class="icon-remove icon-white"></i>
                                             </button>
                                             <button id="comment-edit-${comment.entityId}" class="btn btn-mini commentEditButton"
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/admin_approval.ftl b/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/admin_approval.ftl
index 013988a..9bd730b 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/admin_approval.ftl
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/admin_approval.ftl
@@ -16,7 +16,7 @@
 * specific language governing permissions and limitations
 * under the License.
 -->
-<#-- @ftlvariable name="user" type="org.apache.rave.portal.model.User" -->
+<#-- @ftlvariable name="user" type="org.apache.rave.portal.model.JpaUser" -->
 <#-- @ftlvariable name="portalUrl" type="java.lang.String" -->
 Dear Admin,
 
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/password_reminder.ftl b/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/password_reminder.ftl
index eb677f5..b8fbaee 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/password_reminder.ftl
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/password_reminder.ftl
@@ -16,7 +16,7 @@
 * specific language governing permissions and limitations
 * under the License.
 -->
-<#-- @ftlvariable name="user" type="org.apache.rave.portal.model.User" -->
+<#-- @ftlvariable name="user" type="org.apache.rave.portal.model.JpaUser" -->
 <#-- @ftlvariable name="reminderUrl" type="java.lang.String" -->
 Dear ${user.getUsername()},
 
diff --git a/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/username_reminder.ftl b/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/username_reminder.ftl
index ebdc9ff..9616e5e 100644
--- a/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/username_reminder.ftl
+++ b/rave-portal-resources/src/main/webapp/WEB-INF/mailtemplates/username_reminder.ftl
@@ -16,7 +16,7 @@
 * specific language governing permissions and limitations
 * under the License.
 -->
-<#-- @ftlvariable name="user" type="org.apache.rave.portal.model.User" -->
+<#-- @ftlvariable name="user" type="org.apache.rave.portal.model.JpaUser" -->
 <#-- @ftlvariable name="reminderUrl" type="java.lang.String" -->
 Dear ${user.getUsername()},
 
diff --git a/rave-portal/src/main/dist/LICENSE b/rave-portal/src/main/dist/LICENSE
index 6eafe13..00d059a 100644
--- a/rave-portal/src/main/dist/LICENSE
+++ b/rave-portal/src/main/dist/LICENSE
@@ -2509,6 +2509,36 @@
     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+asm-3.2.jar
+    Containing Project URL: http://asm.ow2.org/
+    
+Copyright (c) 2012 France Télécom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the copyright holders nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.    
+
 ===============================================================================
 
 For Freemarker:
diff --git a/rave-portal/src/test/java/renderer/RenderServiceIntegrationTest.java b/rave-portal/src/test/java/renderer/RenderServiceIntegrationTest.java
index 8718f71..4f11cc8 100644
--- a/rave-portal/src/test/java/renderer/RenderServiceIntegrationTest.java
+++ b/rave-portal/src/test/java/renderer/RenderServiceIntegrationTest.java
@@ -20,11 +20,8 @@
 package renderer;

 

 

-import org.apache.rave.portal.model.Page;

-import org.apache.rave.portal.model.Region;

-import org.apache.rave.portal.model.RegionWidget;

-import org.apache.rave.portal.model.User;

-import org.apache.rave.portal.model.Widget;

+import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.*;

 import org.apache.rave.portal.web.renderer.RenderService;

 import org.apache.rave.portal.web.renderer.ScriptLocation;

 import org.apache.rave.portal.web.renderer.ScriptManager;

@@ -47,9 +44,7 @@
 import java.util.Arrays;

 import java.util.HashMap;

 

-import static org.hamcrest.CoreMatchers.equalTo;

-import static org.hamcrest.CoreMatchers.is;

-import static org.hamcrest.CoreMatchers.notNullValue;

+import static org.hamcrest.CoreMatchers.*;

 import static org.junit.Assert.assertThat;

 

 @RunWith(SpringJUnit4ClassRunner.class)

@@ -87,7 +82,7 @@
         ReflectionTestUtils.setField(metadataRepository, "restOperations", restOperations);

 

         //Setup a mock authenticated user

-        final User authUser = new User(VALID_USER_ID, VALID_USER_NAME);

+        final User authUser = new UserImpl(VALID_USER_ID, VALID_USER_NAME);

         AbstractAuthenticationToken auth = EasyMock.createNiceMock(AbstractAuthenticationToken.class);

         EasyMock.expect(auth.getPrincipal()).andReturn(authUser).anyTimes();

         EasyMock.replay(auth);

@@ -105,17 +100,17 @@
 

     @Test

     public void renderOpenSocial() {

-        Page page = new Page(1L, new User(VALID_USER_ID, VALID_USER_NAME));

-        Region region = new Region(1L, page, 1);

+        Page page = new PageImpl(1L, new UserImpl(VALID_USER_ID, VALID_USER_NAME));

+        Region region = new RegionImpl(1L, page, 1);

         page.setRegions(Arrays.asList(region));

 

-        Widget w = new Widget();

+        WidgetImpl w = new WidgetImpl();

         w.setType("OpenSocial");

-        w.setEntityId(1L);

+        w.setId(1L);

         w.setTitle("Gadget Title");

         w.setUrl("http://www.example.com/gadget.xml");

 

-        RegionWidget rw = new RegionWidget(1L, w, region);

+        RegionWidget rw = new RegionWidgetImpl(1L, w, region);

         region.setRegionWidgets(Arrays.asList(rw));

 

         RenderContext context = new RenderContext();

diff --git a/rave-portal/src/test/resources/test-applicationContext.xml b/rave-portal/src/test/resources/test-applicationContext.xml
index dee7ce2..3cba20a 100644
--- a/rave-portal/src/test/resources/test-applicationContext.xml
+++ b/rave-portal/src/test/resources/test-applicationContext.xml
@@ -22,6 +22,7 @@
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
 
     <import resource="classpath:org/apache/rave/core-applicationContext.xml"/>
+    <import resource="classpath:org/apache/rave/jpa-applicationContext.xml"/>
     <import resource="classpath:org/apache/rave/web-applicationContext.xml"/>
     <import resource="classpath:org/apache/rave/opensocial-provider-applicationContext.xml"/>
 
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java
index 20e9d8e..8bfd6be 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java
@@ -20,7 +20,9 @@
 package org.apache.rave.provider.opensocial.service.impl;

 

 import org.apache.commons.io.FileUtils;

-import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.RegionWidget;

+import org.apache.rave.portal.model.User;

+import org.apache.rave.portal.model.impl.*;

 import org.apache.rave.portal.service.UserService;

 import org.apache.rave.provider.opensocial.exception.SecurityTokenException;

 import org.apache.rave.provider.opensocial.service.SecurityTokenService;

@@ -130,16 +132,16 @@
         SecurityToken securityToken = this.decryptSecurityToken(encryptedSecurityToken);

 

         //Make sure the person is authorized to refresh this token

-        String userId = String.valueOf(userService.getAuthenticatedUser().getEntityId());

+        String userId = String.valueOf(userService.getAuthenticatedUser().getId());

         if (!securityToken.getViewerId().equalsIgnoreCase(userId)) {

             throw new SecurityTokenException("Illegal attempt by user " + userId +

                     " to refresh security token with a viewerId of " + securityToken.getViewerId());

         }

 

         //Create a new RegionWidget instance from it so we can use it to generate a new encrypted token

-        RegionWidget regionWidget = new RegionWidget(securityToken.getModuleId(),

-                new Widget(-1L, securityToken.getAppUrl()),

-                new Region(-1L, new Page(-1L, new User(Long.valueOf(securityToken.getOwnerId()))), -1));

+        RegionWidget regionWidget = new RegionWidgetImpl(securityToken.getModuleId(),

+                new WidgetImpl(-1L, securityToken.getAppUrl()),

+                new RegionImpl(-1L, new PageImpl(-1L, new UserImpl(Long.valueOf(securityToken.getOwnerId()))), -1));

 

         //Create and return the newly encrypted token

         return getEncryptedSecurityToken(regionWidget);

@@ -151,10 +153,10 @@
 

         Map<String, String> values = new HashMap<String, String>();

         values.put(AbstractSecurityToken.Keys.APP_URL.getKey(), regionWidget.getWidget().getUrl());

-        values.put(AbstractSecurityToken.Keys.MODULE_ID.getKey(), String.valueOf(regionWidget.getEntityId()));

+        values.put(AbstractSecurityToken.Keys.MODULE_ID.getKey(), String.valueOf(regionWidget.getId()));

         values.put(AbstractSecurityToken.Keys.OWNER.getKey(),

-                String.valueOf(regionWidget.getRegion().getPage().getOwner().getEntityId()));

-        values.put(AbstractSecurityToken.Keys.VIEWER.getKey(), String.valueOf(user.getEntityId()));

+                String.valueOf(regionWidget.getRegion().getPage().getOwner().getId()));

+        values.put(AbstractSecurityToken.Keys.VIEWER.getKey(), String.valueOf(user.getId()));

         values.put(AbstractSecurityToken.Keys.TRUSTED_JSON.getKey(), "");

 

         BlobCrypterSecurityToken securityToken = new BlobCrypterSecurityToken(container, domain, null, values);

diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/OpenSocialWidgetMetadataResolver.java b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/OpenSocialWidgetMetadataResolver.java
index a3f1ecc..47c6009 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/OpenSocialWidgetMetadataResolver.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/service/impl/OpenSocialWidgetMetadataResolver.java
@@ -20,6 +20,7 @@
 package org.apache.rave.provider.opensocial.service.impl;

 

 import org.apache.rave.portal.model.Widget;

+import org.apache.rave.portal.model.impl.WidgetImpl;

 import org.apache.rave.portal.service.WidgetMetadataResolver;

 import org.apache.rave.provider.opensocial.Constants;

 import org.apache.rave.provider.opensocial.repository.GadgetMetadataRepository;

@@ -52,7 +53,7 @@
      * @return

      */

     public Widget getMetadata(String url) {

-        Widget widget = new Widget();

+        Widget widget = new WidgetImpl();

         JSONObject jsonGadget = null;

         try {

             jsonGadget = (JSONObject) new JSONTokener(gadgetMetadataRepository.getGadgetMetadata(url)).nextValue();

diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java
index 87bc210..bdfead5 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java
@@ -98,7 +98,7 @@
         scriptManager.registerScriptBlock(widgetScript, ScriptLocation.AFTER_RAVE, RenderScope.CURRENT_REQUEST, context);
         logger.debug("Gadget Script Data: " + widgetScript);
 
-        return String.format(MARKUP, item.getEntityId());
+        return String.format(MARKUP, item.getId());
     }
 
     private String getWidgetScript(RegionWidget item) {
@@ -114,15 +114,15 @@
         }
 
         return String.format(SCRIPT_BLOCK,
-                item.getRegion().getEntityId(),
+                item.getRegion().getId(),
                 Constants.WIDGET_TYPE,
-                item.getEntityId(),
+                item.getId(),
                 item.getWidget().getUrl(),
                 securityTokenService.getEncryptedSecurityToken(item),
                 openSocialService.getGadgetMetadata(item.getWidget().getUrl()),
                 userPrefs.toString(),
                 item.isCollapsed(),
-                item.getWidget().getEntityId(),
+                item.getWidget().getId(),
                 item.isLocked(),
                 item.isHideChrome());
     }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java
index 2bf9c93..8607e22 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.provider.opensocial.service;

 

 import org.apache.rave.portal.model.*;

+import org.apache.rave.portal.model.impl.*;

 import org.apache.rave.portal.service.UserService;

 import org.apache.rave.provider.opensocial.service.impl.EncryptedBlobSecurityTokenService;

 import org.apache.shindig.auth.SecurityToken;

@@ -76,21 +77,22 @@
 

     @Before

     public void setup() throws MalformedURLException {

+

         userService = createMock(UserService.class);

         securityTokenService = new EncryptedBlobSecurityTokenService(userService, "default", "default",

                 encryptionKey);

 

-        validPerson = new User(VALID_USER_ID, VALID_USER_NAME);

+        validPerson = new UserImpl(VALID_USER_ID, VALID_USER_NAME);

 

-        validPage = new Page(1L, validPerson);

-        validRegion = new Region(1L, validPage, 1);

+        validPage = new PageImpl(1L, validPerson);

+        validRegion = new RegionImpl(1L, validPage, 1);

         validPage.setRegions(Arrays.asList(validRegion));

 

-        validWidget = new Widget(1L, VALID_URL);

+        validWidget = new WidgetImpl(1L, VALID_URL);

         validWidget.setType("OpenSocial");

         validWidget.setTitle("Widget Title");

 

-        validRegionWidget = new RegionWidget(VALID_REGION_WIDGET_ID, validWidget, validRegion);

+        validRegionWidget = new RegionWidgetImpl(VALID_REGION_WIDGET_ID, validWidget, validRegion);

         validRegion.setRegionWidgets(Arrays.asList(validRegionWidget));

     }

 

@@ -106,7 +108,7 @@
     @Test

     public void getSecurityToken_validWidget_ownerIsNotViewer() throws SecurityTokenException {

         Long expectedOwnerId = 99999L;

-        validPage.setOwner(new User(expectedOwnerId));

+        validPage.setOwner(new UserImpl(expectedOwnerId));

 

         expect(userService.getAuthenticatedUser()).andReturn(validPerson).anyTimes();

         replay(userService);

diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java
index e0381f1..6b46374 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-client/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java
@@ -23,7 +23,10 @@
 import org.apache.rave.portal.model.Region;
 import org.apache.rave.portal.model.RegionWidget;
 import org.apache.rave.portal.model.RegionWidgetPreference;
-import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.RegionImpl;
+import org.apache.rave.portal.model.impl.RegionWidgetImpl;
+import org.apache.rave.portal.model.impl.RegionWidgetPreferenceImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.web.renderer.RenderScope;
 import org.apache.rave.portal.web.renderer.Renderer;
 import org.apache.rave.portal.web.renderer.ScriptLocation;
@@ -76,21 +79,21 @@
         expect(openSocialService.getGadgetMetadata(VALID_GADGET_URL)).andReturn(VALID_METADATA);
         replay(openSocialService);
 
-        Widget w = new Widget();
-        w.setEntityId(1L);
+        WidgetImpl w = new WidgetImpl();
+        w.setId(1L);
         w.setType(Constants.WIDGET_TYPE);
         w.setUrl(VALID_GADGET_URL);
-        Region region = new Region(1L);
-        RegionWidget rw = new RegionWidget();
-        rw.setEntityId(1L);
+        Region region = new RegionImpl(1L);
+        RegionWidget rw = new RegionWidgetImpl();
+        rw.setId(1L);
         rw.setCollapsed(VALID_COLLAPSED);
         rw.setWidget(w);
         rw.setRegion(region);
         rw.setHideChrome(VALID_HIDE_CHROME);
         rw.setLocked(VALID_LOCKED);
-        rw.setPreferences(Arrays.asList(new RegionWidgetPreference(1L, 1L, "color", "blue"),
-                                        new RegionWidgetPreference(2L, 1L, "speed", "fast"),
-                                        new RegionWidgetPreference(3L, 1L, null, null)));
+        rw.setPreferences(Arrays.asList((RegionWidgetPreference)new RegionWidgetPreferenceImpl( 1L, "color", "blue"),
+                                        new RegionWidgetPreferenceImpl(1L, "speed", "fast"),
+                                        new RegionWidgetPreferenceImpl( 1L, null, null)));
 
         final String markup =
             "<script>rave.registerWidget(1, {type: 'OpenSocial'," +
@@ -120,10 +123,10 @@
 
     @Test
     public void render_null() {
-        Widget w = new Widget();
+        WidgetImpl w = new WidgetImpl();
         w.setType(Constants.WIDGET_TYPE);
-        Region region = new Region(1L);
-        RegionWidget rw = new RegionWidget();
+        Region region = new RegionImpl(1L);
+        RegionWidget rw = new RegionWidgetImpl();
         rw.setWidget(w);
         rw.setRegion(region);
 
@@ -147,11 +150,11 @@
 
     @Test(expected = NotSupportedException.class)
     public void render_invalid() {
-        Widget w = new Widget();
+        WidgetImpl w = new WidgetImpl();
         w.setType("NONE");
         w.setUrl("http://www.example.com/gadget.xml");
-        RegionWidget rw = new RegionWidget();
-        rw.setEntityId(1L);
+        RegionWidget rw = new RegionWidgetImpl();
+        rw.setId(1L);
         rw.setWidget(w);
 
         renderer.render(rw, null);
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/pom.xml b/rave-providers/rave-opensocial-provider/rave-opensocial-core/pom.xml
index 54ce52b..5267938 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/pom.xml
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/pom.xml
@@ -46,11 +46,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.apache.openjpa</groupId>
-            <artifactId>openjpa</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-core</artifactId>
         </dependency>
@@ -139,48 +134,6 @@
         </dependency>
     </dependencies>
     <build>
-        <defaultGoal>install</defaultGoal>        
-          <plugins>
-             <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>openjpa-maven-plugin</artifactId>
-                <version>1.2</version>
-                <configuration>
-                    <includes>
-                        org/apache/rave/gadgets/oauth/model/*.class,
-                        org/apache/rave/opensocial/model/*.class,
-                        org/apache/rave/opensocial/repository/impl/JpaApplicationDataRepository$JpaSerializableApplicationData.class,
-                        org/apache/shindig/social/opensocial/jpa/*.class
-                    </includes>
-                    <excludes>
-                        org/apache/shindig/social/opensocial/jpa/EnumDb.class,
-                        org/apache/rave/gadgets/oauth/model/OAuthConsumerStore$KeyType.class
-                    </excludes>
-                    <addDefaultConstructor>true</addDefaultConstructor>
-                    <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
-                </configuration>
-                <executions>
-                    <execution>
-                        <id>enhancer</id>
-                        <phase>process-classes</phase>
-                        <goals>
-                            <goal>enhance</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                  <!-- RAVE-245: Enforce xercesImpl:2.9.1 on the classpath for openjpa-maven-plugin
-                                 to resolve a conflicting classloader resolution when *also* running
-                                 a forked test lifecycle by the maven-cobertura-plugin, 
-                                 e.g. through mvn install cobertura:cobertura                                 
-                  -->
-                  <dependency>
-                    <groupId>xerces</groupId>
-                    <artifactId>xercesImpl</artifactId>
-                    <version>2.9.1</version>
-                  </dependency>
-                </dependencies>
-            </plugin>
-       </plugins>
+        <defaultGoal>install</defaultGoal>
    </build>
 </project>
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java
index 313618f..ecf50a8 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java
@@ -19,18 +19,16 @@
 
 package org.apache.rave.gadgets.oauth.inject;
 
-import java.io.IOException;
-import java.io.InputStream;
-
 import net.oauth.OAuth;
 import net.oauth.OAuthConsumer;
 import net.oauth.OAuthServiceProvider;
 import net.oauth.signature.RSA_SHA1;
 import org.apache.commons.io.IOUtils;
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
 import org.apache.rave.gadgets.oauth.service.OAuthConsumerStoreService;
 import org.apache.rave.gadgets.oauth.service.OAuthTokenInfoService;
+import org.apache.rave.portal.model.OAuthConsumerStore;
+import org.apache.rave.portal.model.OAuthTokenInfo;
+import org.apache.rave.portal.model.impl.OAuthTokenInfoImpl;
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.gadgets.GadgetException;
 import org.apache.shindig.gadgets.oauth.BasicOAuthStore;
@@ -39,6 +37,9 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.ClassPathResource;
 
+import java.io.IOException;
+import java.io.InputStream;
+
 /**
  * {@link OAuthStore} that retrieves the consumer_key, consumer_secret and key_type from the database
  * <p/>
@@ -111,8 +112,9 @@
     @Override
     public void setTokenInfo(SecurityToken securityToken, ConsumerInfo consumerInfo, String serviceName,
                              String tokenName, TokenInfo tokenInfo) throws GadgetException {
-        OAuthTokenInfo oAuthTokenInfo = new OAuthTokenInfo(securityToken,
-                serviceName, tokenName, tokenInfo);
+        OAuthTokenInfo oAuthTokenInfo = new OAuthTokenInfoImpl(securityToken.getAppUrl(),
+                serviceName, tokenName, tokenInfo.getAccessToken(), tokenInfo.getSessionHandle(),
+                tokenInfo.getTokenSecret(), securityToken.getViewerId(), tokenInfo.getTokenExpireMillis());
         tokenInfoService.saveOAuthTokenInfo(oAuthTokenInfo);
     }
 
@@ -130,7 +132,7 @@
      * Creates an {@link OAuthConsumer} based on the OAuth signature method
      *
      * @param provider      {@link net.oauth.OAuthServiceProvider}
-     * @param consumerStore {@link OAuthConsumerStore}
+     * @param consumerStore {@link org.apache.rave.portal.model.OAuthConsumerStore}
      *                      persistent OAuth consumer keys & secrets
      * @return {@link OAuthConsumer} if the signature method is supported
      */
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java
deleted file mode 100644
index 8fcd60f..0000000
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.gadgets.oauth.repository.impl;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
-import org.apache.rave.gadgets.oauth.repository.OAuthConsumerStoreRepository;
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.springframework.stereotype.Repository;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-/**
- * JPA implementation for {@link OAuthConsumerStoreRepository}
- */
-@Repository
-public class JpaOAuthConsumerStoreRepository extends AbstractJpaRepository<OAuthConsumerStore>
-        implements OAuthConsumerStoreRepository {
-
-    @PersistenceContext
-    private EntityManager manager;
-
-
-    public JpaOAuthConsumerStoreRepository() {
-        super(OAuthConsumerStore.class);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName) {
-        TypedQuery<OAuthConsumerStore> query = manager.createNamedQuery(
-                OAuthConsumerStore.FIND_BY_URI_AND_SERVICE_NAME, OAuthConsumerStore.class);
-        query.setParameter(OAuthConsumerStore.GADGET_URI_PARAM, gadgetUri);
-        query.setParameter(OAuthConsumerStore.SERVICE_NAME_PARAM, serviceName);
-        return getSingleResult(query.getResultList());
-    }
-}
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java
deleted file mode 100644
index 46869ca..0000000
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.gadgets.oauth.repository.impl;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
-import org.apache.rave.gadgets.oauth.repository.OAuthTokenInfoRepository;
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.springframework.stereotype.Repository;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-/**
- * JPA implementation for {@link OAuthTokenInfoRepository}
- */
-@Repository
-public class JpaOAuthTokenInfoRepository extends AbstractJpaRepository<OAuthTokenInfo>
-        implements OAuthTokenInfoRepository {
-
-    @PersistenceContext
-    private EntityManager manager;
-
-    public JpaOAuthTokenInfoRepository() {
-        super(OAuthTokenInfo.class);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
-                                             String tokenName, String serviceName) {
-        TypedQuery<OAuthTokenInfo> query = manager.createNamedQuery(OAuthTokenInfo.FIND_OAUTH_TOKEN_INFO,
-                OAuthTokenInfo.class);
-        query.setParameter(OAuthTokenInfo.USER_ID_PARAM, userId);
-        query.setParameter(OAuthTokenInfo.APP_URL_PARAM, appUrl);
-        query.setParameter(OAuthTokenInfo.MODULE_ID_PARAM, moduleId);
-        query.setParameter(OAuthTokenInfo.TOKEN_NAME_PARAM, tokenName);
-        query.setParameter(OAuthTokenInfo.SERVICE_NAME_PARAM, serviceName);
-        return getSingleResult(query.getResultList());
-    }
-
-}
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java
index 768a48e..4d4401b 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java
@@ -19,7 +19,7 @@
 
 package org.apache.rave.gadgets.oauth.service;
 
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.portal.model.OAuthConsumerStore;
 
 /**
  * Service to handle OAuth Consumer store
@@ -27,27 +27,27 @@
 public interface OAuthConsumerStoreService {
 
     /**
-     * Fetches {@link OAuthConsumerStore} based on the gadget location and the service provider
+     * Fetches {@link org.apache.rave.portal.model.OAuthConsumerStore} based on the gadget location and the service provider
      *
      * @param gadgetUri   location of the gadget definition
      * @param serviceName name of the service provider
-     * @return {@link OAuthConsumerStore} or {@literal null} if none matches the criteria
+     * @return {@link org.apache.rave.portal.model.OAuthConsumerStore} or {@literal null} if none matches the criteria
      */
     OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName);
 
     /**
-     * Persists {@link OAuthConsumerStore}
+     * Persists {@link org.apache.rave.portal.model.OAuthConsumerStore}
      *
-     * @param oAuthConsumerStore {@link OAuthConsumerStore} to store
-     * @return persisted {@link OAuthConsumerStore}
+     * @param oAuthConsumerStore {@link org.apache.rave.portal.model.OAuthConsumerStore} to store
+     * @return persisted {@link org.apache.rave.portal.model.OAuthConsumerStore}
      */
 
     OAuthConsumerStore save(OAuthConsumerStore oAuthConsumerStore);
 
     /**
-     * Removes the {@link OAuthConsumerStore} from the database
+     * Removes the {@link org.apache.rave.portal.model.OAuthConsumerStore} from the database
      *
-     * @param oAuthConsumerStore {@link OAuthConsumerStore} to delete
+     * @param oAuthConsumerStore {@link org.apache.rave.portal.model.OAuthConsumerStore} to delete
      */
     void delete(OAuthConsumerStore oAuthConsumerStore);
 }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java
index 8c8932d..836337b 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java
@@ -19,35 +19,35 @@
 
 package org.apache.rave.gadgets.oauth.service;
 
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.portal.model.OAuthTokenInfo;
 
 /**
  * Service to handle OAuth Tokens
  */
 public interface OAuthTokenInfoService {
     /**
-     * Retrieves {@link OAuthTokenInfo}
+     * Retrieves {@link org.apache.rave.portal.model.OAuthTokenInfo}
      *
      * @param userId      unique identifier of gadget viewer
      * @param appUrl      URL of the gadget
      * @param moduleId    the module ID of the application
      * @param tokenName   gadget's nickname for the token to use
      * @param serviceName name of the service provider
-     * @return {@link OAuthTokenInfo} or {@literal null} if none matches the criteria
+     * @return {@link org.apache.rave.portal.model.OAuthTokenInfo} or {@literal null} if none matches the criteria
      */
     OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
                                              String tokenName, String serviceName);
 
     /**
-     * Persists the {@link OAuthTokenInfo} to the data store
+     * Persists the {@link org.apache.rave.portal.model.OAuthTokenInfo} to the data store
      *
-     * @param tokenInfo {@link OAuthTokenInfo} to save
+     * @param tokenInfo {@link org.apache.rave.portal.model.OAuthTokenInfo} to save
      * @return persisted OAuthTokenInfo
      */
     OAuthTokenInfo saveOAuthTokenInfo(OAuthTokenInfo tokenInfo);
 
     /**
-     * Removes the {@link OAuthTokenInfo}'s that match the criteria from the data store
+     * Removes the {@link org.apache.rave.portal.model.OAuthTokenInfo}'s that match the criteria from the data store
      *
      * @param userId      unique identifier of the gadget viewer
      * @param appUrl      URL of the gadget
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java
index fbc7523..0de187e 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java
@@ -19,14 +19,14 @@
 
 package org.apache.rave.gadgets.oauth.service.impl;
 
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
-import org.apache.rave.gadgets.oauth.repository.OAuthConsumerStoreRepository;
+import org.apache.rave.portal.model.OAuthConsumerStore;
+import org.apache.rave.portal.repository.OAuthConsumerStoreRepository;
 import org.apache.rave.gadgets.oauth.service.OAuthConsumerStoreService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 /**
- * JPA implementation for {@link OAuthConsumerStoreService}
+ * Implementation for {@link OAuthConsumerStoreService}
  */
 @Service
 public class DefaultOAuthConsumerStoreService implements OAuthConsumerStoreService {
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java
index b7ada43..cc1e139 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java
@@ -19,8 +19,8 @@
 
 package org.apache.rave.gadgets.oauth.service.impl;
 
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
-import org.apache.rave.gadgets.oauth.repository.OAuthTokenInfoRepository;
+import org.apache.rave.portal.model.OAuthTokenInfo;
+import org.apache.rave.portal.repository.OAuthTokenInfoRepository;
 import org.apache.rave.gadgets.oauth.service.OAuthTokenInfoService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/OpenSocialPersonRepository.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/OpenSocialPersonRepository.java
new file mode 100644
index 0000000..5110a14
--- /dev/null
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/OpenSocialPersonRepository.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.opensocial.repository;
+
+import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.repository.PersonRepository;
+import org.apache.shindig.protocol.model.FilterOperation;
+
+import java.util.List;
+
+
+public interface OpenSocialPersonRepository extends PersonRepository {
+    /**
+     * Gets all people connected to the given user including friends, fellow group members, etc, filtered by the specified field
+     *
+     * @param username the username of the person to query for
+     * @param field the field to filter on
+     * @param operation the type of filter to apply
+     * @param value the value of the specified filter
+     * @return a filtered list of connected individuals
+     */
+    List<Person> findAllConnectedPeople(String username, String field, FilterOperation operation, String value);
+
+    /**
+     * Finds the list of friends for the given person, filtered by the specified field
+     *
+     * @param username the username of the user to find friends for
+     * @param field the field to filter on
+     * @param operation the type of filter to apply
+     * @param value the value of the specified filter
+     * @return a filtered list of friends
+     */
+    List<Person> findFriends(String username, String field, FilterOperation operation, String value);
+
+    /**
+     * Finds a subset of people in the specified group filtered by the specified field
+     *
+     * @param groupId the Id of the group to query
+     * @param field the field to filter on
+     * @param operation the type of filter to apply
+     * @param value the value of the specified filter
+     * @return a filtered list of group members
+     */
+    List<Person> findByGroup(String groupId, String field, FilterOperation operation, String value);
+}
+
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/DecoratingOpenSocialPersonRepository.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/DecoratingOpenSocialPersonRepository.java
new file mode 100644
index 0000000..abe347e
--- /dev/null
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/DecoratingOpenSocialPersonRepository.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.rave.opensocial.repository.impl;
+
+import org.apache.rave.exception.NotSupportedException;
+import org.apache.rave.opensocial.repository.OpenSocialPersonRepository;
+import org.apache.rave.portal.model.Person;
+import org.apache.rave.portal.repository.PersonRepository;
+import org.apache.shindig.protocol.model.FilterOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ *
+ */
+@Repository
+public class DecoratingOpenSocialPersonRepository implements OpenSocialPersonRepository {
+
+    @Autowired
+    private PersonRepository underlying;
+
+    @Override
+    public List<Person> findAllConnectedPeople(String username, String field, FilterOperation operation, String value) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public List<Person> findFriends(String username, String field, FilterOperation operation, String value) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public List<Person> findByGroup(String groupId, String field, FilterOperation operation, String value) {
+        throw new NotSupportedException();
+    }
+
+    @Override
+    public Person findByUsername(String username) {
+        return underlying.findByUsername(username);
+    }
+
+    @Override
+    public List<Person> findAllConnectedPeople(String username) {
+        return underlying.findAllConnectedPeople(username);
+    }
+
+    @Override
+    public List<Person> findAllConnectedPeople(String username, String appId) {
+        return underlying.findAllConnectedPeople(username, appId);
+    }
+
+    @Override
+    public List<Person> findAllConnectedPeopleWithFriend(String username, String friendUsername) {
+        return underlying.findAllConnectedPeopleWithFriend(username, friendUsername);
+    }
+
+    @Override
+    public List<Person> findFriends(String username) {
+        return underlying.findFriends(username);
+    }
+
+    @Override
+    public List<Person> findFriends(String username, String appId) {
+        return underlying.findFriends(username, appId);
+    }
+
+    @Override
+    public List<Person> findFriendsWithFriend(String username, String friendUsername) {
+        return underlying.findFriendsWithFriend(username, friendUsername);
+    }
+
+    @Override
+    public List<Person> findByGroup(String groupId) {
+        return underlying.findByGroup(groupId);
+    }
+
+    @Override
+    public List<Person> findByGroup(String groupId, String appId) {
+        return underlying.findByGroup(groupId, appId);
+    }
+
+    @Override
+    public List<Person> findByGroupWithFriend(String groupId, String friendUsername) {
+        return underlying.findByGroupWithFriend(groupId, friendUsername);
+    }
+
+    @Override
+    public Class<? extends Person> getType() {
+        return underlying.getType();
+    }
+
+    @Override
+    public Person get(long id) {
+        return underlying.get(id);
+    }
+
+    @Override
+    public Person save(Person item) {
+        return underlying.save(item);
+    }
+
+    @Override
+    public void delete(Person item) {
+        underlying.delete(item);
+    }
+}
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/JpaPersonRepository.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/JpaPersonRepository.java
deleted file mode 100644
index f89552f..0000000
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/repository/impl/JpaPersonRepository.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.rave.opensocial.repository.impl;
-
-import org.apache.rave.exception.NotSupportedException;
-import org.apache.rave.portal.model.Group;
-import org.apache.rave.portal.model.Person;
-import org.apache.rave.opensocial.repository.PersonRepository;
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
-import org.apache.rave.util.CollectionUtils;
-import org.apache.shindig.protocol.model.FilterOperation;
-import org.springframework.stereotype.Repository;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.TypedQuery;
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
-
-/**
- *
- */
-@Repository
-public class JpaPersonRepository extends AbstractJpaRepository<Person> implements PersonRepository{
-
-    @PersistenceContext
-    private EntityManager manager;
-
-    public JpaPersonRepository() {
-        super(Person.class);
-    }
-
-    @Override
-    public Person findByUsername(String username) {
-        TypedQuery<Person> query = manager.createNamedQuery(Person.FIND_BY_USERNAME, Person.class);
-        query.setParameter(Person.USERNAME_PARAM, username);
-        return getSingleResult(query.getResultList());
-    }
-
-    @Override
-    public List<Person> findAllConnectedPeople(String username) {
-        List<Person> connections = new ArrayList<Person>();
-        connections.addAll(findFriends(username));
-        TypedQuery<Person> members = manager.createNamedQuery(Person.FIND_BY_GROUP_MEMBERSHIP, Person.class);
-        members.setParameter(Person.USERNAME_PARAM, username);
-        CollectionUtils.addUniqueValues(members.getResultList(), connections);
-        return connections;
-    }
-
-    @Override
-    public List<Person> findAllConnectedPeople(String username, String appId) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findAllConnectedPeople(String username, String field, FilterOperation operation, String value) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findAllConnectedPeopleWithFriend(String username, String friendUsername) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findFriends(String username) {
-        TypedQuery<Person> friends = manager.createNamedQuery(Person.FIND_FRIENDS_BY_USERNAME, Person.class);
-        friends.setParameter(Person.USERNAME_PARAM, username);
-        return friends.getResultList();
-    }
-
-    @Override
-    public List<Person> findFriends(String username, String appId) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findFriends(String username, String field, FilterOperation operation, String value) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findFriendsWithFriend(String username, String friendUsername) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findByGroup(String groupId) {
-        TypedQuery<Group> query = manager.createNamedQuery(Group.FIND_BY_TITLE, Group.class);
-        query.setParameter(Group.GROUP_ID_PARAM, groupId);
-        Group result = getSingleResult(query.getResultList());
-        return result == null ? new ArrayList<Person>() : result.getMembers();
-    }
-
-    @Override
-    public List<Person> findByGroup(String groupId, String appId) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findByGroup(String groupId, String field, FilterOperation operation, String value) {
-        throw new NotSupportedException();
-    }
-
-    @Override
-    public List<Person> findByGroupWithFriend(String groupId, String friendUsername) {
-        throw new NotSupportedException();
-    }
-}
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultAppDataService.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultAppDataService.java
index acd6abf..47947c4 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultAppDataService.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultAppDataService.java
@@ -20,10 +20,11 @@
 package org.apache.rave.opensocial.service.impl;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.rave.opensocial.model.ApplicationData;
-import org.apache.rave.portal.model.Person;
-import org.apache.rave.opensocial.repository.ApplicationDataRepository;
+import org.apache.rave.portal.model.ApplicationData;
+import org.apache.rave.portal.model.impl.ApplicationDataImpl;
+import org.apache.rave.portal.repository.ApplicationDataRepository;
 import org.apache.rave.opensocial.service.SimplePersonService;
+import org.apache.rave.portal.model.Person;
 import org.apache.rave.service.LockService;
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.common.util.ImmediateFuture;
@@ -162,7 +163,7 @@
 
             //if there is no data, create an empty object to store the data in that we'll save when we're done
             if (applicationData == null) {
-                applicationData = new ApplicationData(null, personId, appId, new HashMap<String, String>());
+                applicationData = new ApplicationDataImpl(null, personId, appId, new HashMap<String, String>());
             }
 
             //if the fields parameter is empty, we can just use the values map directly since this is a full update
@@ -231,8 +232,8 @@
 
     private List<String> convertPeopleToUserIds(List<Person> people) {
         List<String> ids = new ArrayList<String>(people.size());
-        for (Person person : people) {
-            ids.add(String.valueOf(person.getEntityId()));
+        for (org.apache.rave.portal.model.Person person : people) {
+            ids.add(String.valueOf(person.getUsername()));
         }
         return ids;
     }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultPersonService.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultPersonService.java
index 375887e..950ba06 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultPersonService.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/DefaultPersonService.java
@@ -20,7 +20,7 @@
 package org.apache.rave.opensocial.service.impl;
 
 import com.google.common.collect.Lists;
-import org.apache.rave.opensocial.repository.PersonRepository;
+import org.apache.rave.opensocial.repository.OpenSocialPersonRepository;
 import org.apache.rave.opensocial.service.SimplePersonService;
 import org.apache.rave.util.CollectionUtils;
 import org.apache.shindig.auth.SecurityToken;
@@ -47,10 +47,10 @@
 @Service
 public class DefaultPersonService implements PersonService, SimplePersonService {
 
-    private final PersonRepository repository;
+    private final OpenSocialPersonRepository repository;
 
     @Autowired
-    public DefaultPersonService(PersonRepository repository) {
+    public DefaultPersonService(OpenSocialPersonRepository repository) {
         this.repository = repository;
     }
 
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/FieldRestrictingPerson.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/FieldRestrictingPerson.java
index c86abbc..f2ccae1 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/FieldRestrictingPerson.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/java/org/apache/rave/opensocial/service/impl/FieldRestrictingPerson.java
@@ -26,6 +26,7 @@
 import org.apache.shindig.protocol.model.Enum;
 import org.apache.shindig.protocol.model.EnumImpl;
 import org.apache.shindig.social.core.model.*;
+import org.apache.shindig.social.core.model.AddressImpl;
 import org.apache.shindig.social.opensocial.model.*;
 import org.apache.shindig.social.opensocial.model.Address;
 import org.apache.shindig.social.opensocial.model.Organization;
@@ -110,7 +111,7 @@
 
     @Override
     public List<Address> getAddresses() {
-        return displayField(Field.ADDRESSES) ? convertAddresses(internal.getAddresses()) : null;        
+        return displayField(Field.ADDRESSES) ? convertAddresses(internal.getAddresses()) : null;
     }
 
     @Override
@@ -340,7 +341,7 @@
     //REQUIRED FIELD
     @Override
     public String getId() {
-        return internal.getEntityId().toString();
+        return internal.getUsername();
     }
 
     @Override
@@ -826,7 +827,7 @@
     private static Url convertToUrl(PersonProperty property) {
         return new UrlImpl(property.getValue(), property.getExtendedValue(), property.getQualifier());
     }
-    
+
     private List<Address> convertAddresses(List<org.apache.rave.portal.model.Address> addresses) {
         List<Address> converted = new ArrayList<Address>();
         if(addresses != null) {
@@ -896,7 +897,7 @@
     }
 
     private Organization convertOrganization(org.apache.rave.portal.model.Organization org) {
-        Organization converted = new OrganizationImpl();
+        Organization converted = new org.apache.shindig.social.core.model.OrganizationImpl();
         converted.setAddress(convertAddress(org.getAddress()));
         converted.setDescription(org.getDescription());
         converted.setStartDate(org.getStartDate());
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml
deleted file mode 100644
index 19c59fe..0000000
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/main/resources/META-INF/persistence.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one
-  ~ or more contributor license agreements.  See the NOTICE file
-  ~ distributed with this work for additional information
-  ~ regarding copyright ownership.  The ASF licenses this file
-  ~ to you 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.
-  -->
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
-  version="2.0">
-  <persistence-unit name="raveShindigPersistenceUnit" transaction-type="RESOURCE_LOCAL">
-      <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-      <class>org.apache.rave.portal.model.Person</class>
-      <class>org.apache.rave.portal.model.PageLayout</class>
-      <class>org.apache.rave.portal.model.Group</class>
-      <class>org.apache.rave.portal.model.PersonAssociation</class>
-      <class>org.apache.rave.portal.model.PersonProperty</class>
-      <class>org.apache.rave.portal.model.Address</class>
-      <class>org.apache.rave.portal.model.Organization</class>
-      <class>org.apache.rave.opensocial.model.ApplicationData</class>
-      <class>org.apache.rave.opensocial.repository.impl.JpaApplicationDataRepository$JpaSerializableApplicationData</class>
-      <class>org.apache.rave.gadgets.oauth.model.OAuthTokenInfo</class>
-      <class>org.apache.rave.gadgets.oauth.model.OAuthConsumerStore</class>
-  </persistence-unit>
-
-</persistence>
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java
index 88c6d05..3c7af3c 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java
@@ -19,13 +19,12 @@
 
 package org.apache.rave.gadgets.oauth.inject;
 
-import java.io.IOException;
-import java.util.Date;
-
 import net.oauth.OAuth;
 import net.oauth.OAuthServiceProvider;
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.portal.model.OAuthConsumerStore;
+import org.apache.rave.portal.model.OAuthTokenInfo;
+import org.apache.rave.portal.model.impl.OAuthConsumerStoreImpl;
+import org.apache.rave.portal.model.impl.OAuthTokenInfoImpl;
 import org.apache.rave.gadgets.oauth.service.OAuthConsumerStoreService;
 import org.apache.rave.gadgets.oauth.service.OAuthTokenInfoService;
 import org.apache.shindig.auth.SecurityToken;
@@ -36,9 +35,12 @@
 import org.junit.Test;
 import org.springframework.test.util.ReflectionTestUtils;
 
+import java.io.IOException;
+import java.util.Date;
+
 import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
-import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * Test for {@link DefaultOAuthStore}
@@ -56,7 +58,7 @@
 
     @Test
     public void testGetConsumerKeyAndSecret() throws Exception {
-        OAuthConsumerStore consumerStore = new OAuthConsumerStore();
+        OAuthConsumerStore consumerStore = new OAuthConsumerStoreImpl();
         consumerStore.setGadgetUri(GADGET_URI);
         consumerStore.setConsumerKey("gadgetConsumer");
         consumerStore.setConsumerSecret(CONSUMER_SECRET);
@@ -81,13 +83,13 @@
     public void testGetTokenInfo() throws Exception {
         final String testTokenName = "testTokenName";
 
-        OAuthTokenInfo oAuthTokenInfo = new OAuthTokenInfo();
+        OAuthTokenInfo oAuthTokenInfo = new OAuthTokenInfoImpl();
         oAuthTokenInfo.setTokenName(testTokenName);
         oAuthTokenInfo.setTokenSecret(CONSUMER_SECRET);
         OAuthStore.ConsumerInfo consumerInfo = createMock(OAuthStore.ConsumerInfo.class);
 
         expect(tokenInfoService.findOAuthTokenInfo(token.getViewerId(), token.getAppUrl(),
-                OAuthTokenInfo.MODULE_ID, testTokenName,
+                OAuthTokenInfoImpl.MODULE_ID, testTokenName,
                 SERVICE_NAME)).andReturn(oAuthTokenInfo);
         replay(tokenInfoService);
 
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java
index d633fba..85a2581 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java
@@ -19,8 +19,9 @@
 
 package org.apache.rave.gadgets.oauth.service;
 
-import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
-import org.apache.rave.gadgets.oauth.repository.OAuthConsumerStoreRepository;
+import org.apache.rave.portal.model.OAuthConsumerStore;
+import org.apache.rave.portal.model.impl.OAuthConsumerStoreImpl;
+import org.apache.rave.portal.repository.OAuthConsumerStoreRepository;
 import org.apache.rave.gadgets.oauth.service.impl.DefaultOAuthConsumerStoreService;
 import org.junit.Before;
 import org.junit.Test;
@@ -69,7 +70,7 @@
     }
 
     OAuthConsumerStore getOAuthConsumerStore() {
-        OAuthConsumerStore consumerStore = new OAuthConsumerStore();
+        OAuthConsumerStore consumerStore = new OAuthConsumerStoreImpl();
         consumerStore.setCallbackUrl("http://oauth.gmodules.com/gadgets/oauthcallback");
         consumerStore.setConsumerKey("gadgetConsumer");
         consumerStore.setConsumerSecret("gadgetSecret");
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java
index 3ab8bdb..b3a434d 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java
@@ -19,8 +19,9 @@
 
 package org.apache.rave.gadgets.oauth.service;
 
-import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
-import org.apache.rave.gadgets.oauth.repository.OAuthTokenInfoRepository;
+import org.apache.rave.portal.model.OAuthTokenInfo;
+import org.apache.rave.portal.model.impl.OAuthTokenInfoImpl;
+import org.apache.rave.portal.repository.OAuthTokenInfoRepository;
 import org.apache.rave.gadgets.oauth.service.impl.DefaultOAuthTokenInfoService;
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.gadgets.oauth.OAuthStore;
@@ -28,11 +29,7 @@
 import org.junit.Test;
 
 import static junit.framework.Assert.assertEquals;
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
+import static org.easymock.EasyMock.*;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
@@ -106,6 +103,8 @@
         expect(tokenInfo.getTokenExpireMillis()).andReturn(3600000L);
         expect(tokenInfo.getTokenSecret()).andReturn("tokenSecret");
         replay(securityToken, tokenInfo);
-        return new OAuthTokenInfo(securityToken, SERVICE_NAME, TOKEN_NAME, tokenInfo);
+        return new OAuthTokenInfoImpl(securityToken.getAppUrl(), SERVICE_NAME, TOKEN_NAME, tokenInfo.getAccessToken(),
+                tokenInfo.getSessionHandle(), tokenInfo.getTokenSecret(),
+                securityToken.getViewerId(), tokenInfo.getTokenExpireMillis());
     }
 }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/inject/SpringBindingModuleTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/inject/SpringBindingModuleTest.java
index 8f4ee2d..495f7ae 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/inject/SpringBindingModuleTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/inject/SpringBindingModuleTest.java
@@ -22,24 +22,15 @@
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import org.apache.rave.opensocial.service.impl.DefaultPersonService;
-import org.apache.rave.persistence.BasicEntity;
-import org.apache.rave.persistence.jpa.AbstractJpaRepository;
 import org.apache.shindig.social.opensocial.spi.PersonService;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.orm.jpa.LocalEntityManagerFactoryBean;
-import org.springframework.stereotype.Repository;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
 
 @RunWith(SpringJUnit4ClassRunner.class)
@@ -70,25 +61,6 @@
         assertThat(personService1, is(sameInstance(personService2)));
     }
 
-    @Test
-    public void bindsProxiedBean() {
-        LocalEntityManagerFactoryBean factory = injector.getInstance(LocalEntityManagerFactoryBean.class);
-        assertThat(factory, is(not(nullValue())));
-    }
 
-    @Test
-    public void multipleRepositories() {
-        TestRepo repo = injector.getInstance(TestRepo.class);
-        assertThat(repo, is(not(nullValue())));
-    }
 
-    public static interface TestRepo extends org.apache.rave.persistence.Repository<BasicEntity> {}
-
-    @Repository
-    public static class JpaTestRepo extends AbstractJpaRepository<BasicEntity> implements TestRepo {
-
-        protected JpaTestRepo() {
-            super(BasicEntity.class);
-        }
-    }
 }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/AppDataServiceTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/AppDataServiceTest.java
index 7880ef5..e62c9d7 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/AppDataServiceTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/AppDataServiceTest.java
@@ -19,10 +19,12 @@
 
 package org.apache.rave.opensocial.service;
 
-import org.apache.rave.opensocial.model.ApplicationData;
+import org.apache.rave.portal.model.ApplicationData;
+import org.apache.rave.portal.model.impl.ApplicationDataImpl;
 import org.apache.rave.portal.model.Person;
-import org.apache.rave.opensocial.repository.ApplicationDataRepository;
+import org.apache.rave.portal.repository.ApplicationDataRepository;
 import org.apache.rave.opensocial.service.impl.DefaultAppDataService;
+import org.apache.rave.portal.model.impl.PersonImpl;
 import org.apache.rave.service.LockService;
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.protocol.DataCollection;
@@ -61,7 +63,7 @@
     private Map<String, String> validApplicationDataMap;
     private ApplicationData validApplicationData;
 
-    private Person validPerson;
+    private org.apache.rave.portal.model.Person validPerson;
 
     @Before
     public void setup() {
@@ -74,11 +76,11 @@
         validApplicationDataMap.put("color", "blue");
         validApplicationDataMap.put("speed", "fast");
         validApplicationDataMap.put("state", "MA");
-        validApplicationData = new ApplicationData(VALID_APPLICATION_DATA_ID, VALID_VIEWER_ID, VALID_APPLICATION_ID,
+        validApplicationData = new ApplicationDataImpl(VALID_APPLICATION_DATA_ID, VALID_VIEWER_ID, VALID_APPLICATION_ID,
                 validApplicationDataMap);
 
-        validPerson = new Person();
-        validPerson.setEntityId(Long.valueOf(VALID_VIEWER_ID));
+        validPerson = new PersonImpl();
+        validPerson.setUsername(VALID_VIEWER_ID);
     }
 
     @Test
@@ -162,7 +164,7 @@
 
     @Test
     public void deletePersonData_validRequest_emptyApplicationData() throws Exception {
-        ApplicationData applicationData = new ApplicationData();
+        ApplicationData applicationData = new ApplicationDataImpl();
         testDeletePersonDataNoAppDataExpected(applicationData);
     }
 
@@ -305,11 +307,11 @@
 
         appDataService.deletePersonData(userId, groupId, VALID_APPLICATION_ID, fieldsToDelete, securityToken);
 
-        ApplicationData expectedApplicationData = new ApplicationData(applicationData.getEntityId(),
+        ApplicationData expectedApplicationData = new ApplicationDataImpl(applicationData.getId(),
                 applicationData.getUserId(), applicationData.getAppUrl(), expectedApplicationDataAfterDelete);
 
         ApplicationData actualApplicationData = capturedApplicationData.getValue();
-        assertEquals(expectedApplicationData.getEntityId(), actualApplicationData.getEntityId());
+        assertEquals(expectedApplicationData.getId(), actualApplicationData.getId());
         assertEquals(expectedApplicationData.getUserId(), actualApplicationData.getUserId());
         assertEquals(expectedApplicationData.getAppUrl(), actualApplicationData.getAppUrl());
         assertEquals(expectedApplicationData.getData(), actualApplicationData.getData());
@@ -365,13 +367,13 @@
 
         appDataService.updatePersonData(userId, groupId, VALID_APPLICATION_ID, fields, values, securityToken);
 
-        ApplicationData expectedApplicationData = applicationData == null ? new ApplicationData(null, VALID_USER_ID,
+        ApplicationDataImpl expectedApplicationData = applicationData == null ? new ApplicationDataImpl(null, VALID_USER_ID,
                 VALID_APPLICATION_ID, expectedApplicationDataAfterUpdate) :
-                new ApplicationData(applicationData.getEntityId(), applicationData.getUserId(),
+                new ApplicationDataImpl(applicationData.getId(), applicationData.getUserId(),
                         applicationData.getAppUrl(), expectedApplicationDataAfterUpdate);
 
         ApplicationData actualApplicationData = capturedApplicationData.getValue();
-        assertEquals(expectedApplicationData.getEntityId(), actualApplicationData.getEntityId());
+        assertEquals(expectedApplicationData.getId(), actualApplicationData.getId());
         assertEquals(expectedApplicationData.getUserId(), actualApplicationData.getUserId());
         assertEquals(expectedApplicationData.getAppUrl(), actualApplicationData.getAppUrl());
         assertEquals(expectedApplicationData.getData(), actualApplicationData.getData());
@@ -390,8 +392,8 @@
 
     private List<String> convertPeopleToUserIds(List<Person> people) {
         List<String> ids = new ArrayList<String>(people.size());
-        for (Person person : people) {
-            ids.add(String.valueOf(person.getEntityId()));
+        for (org.apache.rave.portal.model.Person person : people) {
+            ids.add(String.valueOf(person.getUsername()));
         }
         return ids;
     }
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java
index b2e6983..f031147 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/FieldRestrictingPersonTest.java
@@ -22,24 +22,22 @@
 
 import org.apache.rave.exception.NotSupportedException;
 import org.apache.rave.opensocial.service.impl.FieldRestrictingPerson;
-import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.model.PersonProperty;
+import org.apache.rave.portal.model.impl.AddressImpl;
+import org.apache.rave.portal.model.impl.PersonImpl;
+import org.apache.rave.portal.model.impl.PersonPropertyImpl;
 import org.apache.rave.portal.model.util.ModelUtils;
 import org.apache.shindig.protocol.model.EnumImpl;
-import org.apache.shindig.social.core.model.AddressImpl;
 import org.apache.shindig.social.core.model.BodyTypeImpl;
 import org.apache.shindig.social.core.model.UrlImpl;
 import org.apache.shindig.social.opensocial.model.*;
-import org.apache.shindig.social.opensocial.model.Address;
-import org.apache.shindig.social.opensocial.model.Person;
 import org.junit.Test;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.fail;
 
@@ -87,7 +85,7 @@
     @Test
     public void getId() {
         Person p = new FieldRestrictingPerson(getTestPerson(), null);
-        assertThat(p.getId(), is(equalTo(ID)));
+        assertThat(p.getId(), is(equalTo(USERNAME)));
     }
     @Test
     public void getDisplayName() {
@@ -303,19 +301,19 @@
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.LIVING_ARRANGEMENT));
         assertThat(p.getLivingArrangement(), is(nullValue()));
     }
-    
+
     @Test
     public void getLookingFor_set() {
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.LOOKING_FOR));
         assertThat(p.getLookingFor().size(), is(equalTo(1)));
     }
-    
+
     @Test
     public void getMovies_set() {
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.MOVIES));
         assertThat(p.getMovies().isEmpty(), is(true));
     }
-    
+
     @Test
     public void getMusic_set() {
         Person p = new FieldRestrictingPerson(getTestPerson(), getFieldSet(Person.Field.MUSIC));
@@ -485,17 +483,17 @@
     public void setMovies() {
         new FieldRestrictingPerson(null, null).setMovies(new ArrayList<String>());
     }
-    
+
     @Test(expected = NotSupportedException.class)
     public void setLookingFor() {
         new FieldRestrictingPerson(null, null).setLookingFor(new ArrayList<org.apache.shindig.protocol.model.Enum<LookingFor>>());
     }
-    
+
     @Test(expected = NotSupportedException.class)
     public void setLivingArrangement() {
         new FieldRestrictingPerson(null, null).setLivingArrangement(SUFFIX);
     }
-    
+
     @Test(expected = NotSupportedException.class)
     public void setUpdated() {
         new FieldRestrictingPerson(null, null).setUpdated(new Date());
@@ -583,7 +581,7 @@
 
     @Test(expected = NotSupportedException.class)
     public void setCurrentLocation() {
-        new FieldRestrictingPerson(null, null).setCurrentLocation(new AddressImpl());
+        new FieldRestrictingPerson(null, null).setCurrentLocation(new org.apache.shindig.social.core.model.AddressImpl());
     }
 
     @Test(expected = NotSupportedException.class)
@@ -622,8 +620,7 @@
     }
 
     private org.apache.rave.portal.model.Person getTestPerson() {
-        org.apache.rave.portal.model.Person person = new org.apache.rave.portal.model.Person();
-        person.setEntityId(1L);
+        org.apache.rave.portal.model.Person person = new PersonImpl();
         person.setUsername(USERNAME);
         person.setAboutMe(ABOUT_ME);
         person.setAdditionalName(ADDITIONAL_NAME);
@@ -636,25 +633,25 @@
         person.setPreferredName(PREFERRED_NAME);
         person.setStatus(STATUS);
         List<PersonProperty> properties = new ArrayList<PersonProperty>();
-        properties.add(new PersonProperty(1L, "gender", Person.Gender.female.toString(), null, "", false));
-        properties.add(new PersonProperty(1L, "drinker", Drinker.HEAVILY.toString(), null, "", false));
-        properties.add(new PersonProperty(1L, "age", AGE.toString(), null, "", false));
-        properties.add(new PersonProperty(1L, "birthday", BIRTHDAY_STRING, null, "", false));
-        properties.add(new PersonProperty(1L, "bodyType", BODY_BUILD, null, "build", false));
-        properties.add(new PersonProperty(1L, "bodyType", BODY_EYE_COLOR, null, "eyeColor", false));
-        properties.add(new PersonProperty(1L, "bodyType", "25.24", null, "height", false));
-        properties.add(new PersonProperty(1L, "ims", IM_1, null, IM_PROVIDER_1, true));
-        properties.add(new PersonProperty(1L, "ims", IM_2, null, IM_PROVIDER_2, false));
-        properties.add(new PersonProperty(1L, "emails", E_MAIL_ADDRESS_2, null, "personal", false));
-        properties.add(new PersonProperty(1L, "emails", E_MAIL_ADDRESS_3, null, "junk", true));
-        properties.add(new PersonProperty(1L, "activities", ACTIVITY_1, null, "", false));
-        properties.add(new PersonProperty(1L, "activities", ACTIVITY_2, null, "", false));
-        properties.add(new PersonProperty(1L, "profileSong", LINK_VALUE, LINK_TEXT, null, false));
-        properties.add(new PersonProperty(1L, "lookingFor", LookingFor.FRIENDS.toString(), null, null, false));
-        properties.add(new PersonProperty(1L, "currentLocation", QUALIFIER, null, null, null));
-        properties.add(new PersonProperty(1L, "account", IM_1, "1", IM_PROVIDER_1, false));
+        properties.add(new PersonPropertyImpl(1L, "gender", Person.Gender.female.toString(), null, "", false));
+        properties.add(new PersonPropertyImpl(1L, "drinker", Drinker.HEAVILY.toString(), null, "", false));
+        properties.add(new PersonPropertyImpl(1L, "age", AGE.toString(), null, "", false));
+        properties.add(new PersonPropertyImpl(1L, "birthday", BIRTHDAY_STRING, null, "", false));
+        properties.add(new PersonPropertyImpl(1L, "bodyType", BODY_BUILD, null, "build", false));
+        properties.add(new PersonPropertyImpl(1L, "bodyType", BODY_EYE_COLOR, null, "eyeColor", false));
+        properties.add(new PersonPropertyImpl(1L, "bodyType", "25.24", null, "height", false));
+        properties.add(new PersonPropertyImpl(1L, "ims", IM_1, null, IM_PROVIDER_1, true));
+        properties.add(new PersonPropertyImpl(1L, "ims", IM_2, null, IM_PROVIDER_2, false));
+        properties.add(new PersonPropertyImpl(1L, "emails", E_MAIL_ADDRESS_2, null, "personal", false));
+        properties.add(new PersonPropertyImpl(1L, "emails", E_MAIL_ADDRESS_3, null, "junk", true));
+        properties.add(new PersonPropertyImpl(1L, "activities", ACTIVITY_1, null, "", false));
+        properties.add(new PersonPropertyImpl(1L, "activities", ACTIVITY_2, null, "", false));
+        properties.add(new PersonPropertyImpl(1L, "profileSong", LINK_VALUE, LINK_TEXT, null, false));
+        properties.add(new PersonPropertyImpl(1L, "lookingFor", LookingFor.FRIENDS.toString(), null, null, false));
+        properties.add(new PersonPropertyImpl(1L, "currentLocation", QUALIFIER, null, null, null));
+        properties.add(new PersonPropertyImpl(1L, "account", IM_1, "1", IM_PROVIDER_1, false));
         person.setProperties(properties);
-        org.apache.rave.portal.model.Address address = new org.apache.rave.portal.model.Address();
+        org.apache.rave.portal.model.Address address = new AddressImpl();
         address.setCountry(COUNTRY);
         address.setLatitude(LATITUDE);
         address.setLongitude(LONGITUDE);
@@ -664,7 +661,7 @@
         address.setStreetAddress(STREET);
         address.setQualifier(QUALIFIER);
         List<org.apache.rave.portal.model.Address> addresses = new ArrayList<org.apache.rave.portal.model.Address>();
-        addresses.add(new org.apache.rave.portal.model.Address());
+        addresses.add(new AddressImpl());
         addresses.add(address);
         person.setAddresses(addresses);
 
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/PersonServiceTest.java b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/PersonServiceTest.java
index 019f33d..586ad39 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/PersonServiceTest.java
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/java/org/apache/rave/opensocial/service/PersonServiceTest.java
@@ -20,9 +20,10 @@
 package org.apache.rave.opensocial.service;
 
 import com.google.common.collect.Lists;
-import org.apache.rave.opensocial.repository.PersonRepository;
+import org.apache.rave.opensocial.repository.OpenSocialPersonRepository;
 import org.apache.rave.opensocial.service.impl.DefaultPersonService;
 import org.apache.rave.opensocial.service.impl.FieldRestrictingPerson;
+import org.apache.rave.portal.model.impl.PersonImpl;
 import org.apache.shindig.auth.SecurityToken;
 import org.apache.shindig.protocol.ProtocolException;
 import org.apache.shindig.protocol.RestfulCollection;
@@ -42,15 +43,9 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.is;
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.*;
 import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.nullValue;
 import static org.junit.Assert.assertThat;
 
 public class PersonServiceTest {
@@ -62,13 +57,13 @@
     private static final String ID_1 = "1234";
     private static final String GROUP_ID = "BOO";
     private PersonService service;
-    private PersonRepository repository;
+    private OpenSocialPersonRepository repository;
     private SecurityToken token;
 
     @Before
     public void setup() {
         token = createNiceMock(SecurityToken.class);
-        repository = createNiceMock(PersonRepository.class);
+        repository = createNiceMock(OpenSocialPersonRepository.class);
         service = new DefaultPersonService(repository);
     }
 
@@ -507,16 +502,14 @@
     }
 
     private org.apache.rave.portal.model.Person getDbPerson() {
-        org.apache.rave.portal.model.Person dbPerson = new org.apache.rave.portal.model.Person();
-        dbPerson.setEntityId(Long.parseLong(ID_1));
+        PersonImpl dbPerson = new PersonImpl();
         dbPerson.setUsername(ID_1);
         dbPerson.setDisplayName(DISPLAY_NAME);
         return dbPerson;
     }
 
     private org.apache.rave.portal.model.Person getDbPerson(Long id) {
-        org.apache.rave.portal.model.Person dbPerson = new org.apache.rave.portal.model.Person();
-        dbPerson.setEntityId(id);
+        PersonImpl dbPerson = new PersonImpl();
         dbPerson.setUsername(id.toString());
         dbPerson.setDisplayName(DISPLAY_NAME);
         return dbPerson;
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/resources/rave-shindig-test-applicationContext.xml b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/resources/rave-shindig-test-applicationContext.xml
index 4479bdd..e54a5ca 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/resources/rave-shindig-test-applicationContext.xml
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-core/src/test/resources/rave-shindig-test-applicationContext.xml
@@ -41,52 +41,27 @@
     <!-- enable the use of the @AspectJ style of Spring AOP -->
     <aop:aspectj-autoproxy />
 
-    <context:component-scan base-package="org.apache.rave.commoncontainer" annotation-config="true"/>
+<!--    <context:component-scan base-package="org.apache.rave.commoncontainer" annotation-config="true"/>
     <context:component-scan base-package="org.apache.rave.gadgets" annotation-config="true"/>
     <context:component-scan base-package="org.apache.rave.inject" annotation-config="true"/>
     <context:component-scan base-package="org.apache.rave.portal.model" annotation-config="true"/>
     <context:component-scan base-package="org.apache.rave.portal.repository" annotation-config="true"/>
     <context:component-scan base-package="org.apache.rave.opensocial" annotation-config="true"/>
-    <context:component-scan base-package="org.apache.rave.service" annotation-config="true"/>
-
-    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
-        <property name="entityManagerFactory" ref="entityManagerFactory"/>
+    <context:component-scan base-package="org.apache.rave.service" annotation-config="true"/>-->
+    <bean id="mockPersonRepo" class="org.easymock.EasyMock" factory-method="createNiceMock">
+        <constructor-arg value="org.apache.rave.opensocial.repository.OpenSocialPersonRepository"/>
     </bean>
 
-    <tx:annotation-driven transaction-manager="transactionManager"/>
-
-    <bean id="entityManagerFactory"
-          class="org.apache.rave.persistence.jpa.PopulatedLocalContainerEntityManagerFactory">
-        <property name="persistenceUnitName" value="raveShindigPersistenceUnit"/>
-        <property name="dataSource" ref="dataSource"/>
-        <property name="populator" ref="dataSourcePopulator"/>
-        <property name="jpaVendorAdapter">
-            <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
-                  p:databasePlatform="${rave-shindig.jpaVendorAdapter.databasePlatform}"
-                  p:database="${rave-shindig.jpaVendorAdapter.database}"
-                  p:showSql="${rave-shindig.jpaVendorAdapter.showSql}"/>
-        </property>
-        <property name="jpaPropertyMap">
-            <map>
-                <entry key="openjpa.Log" value="${rave-shindig.openjpa.Log}"/>
-                <entry key="openjpa.RuntimeUnenhancedClasses" value="${rave-shindig.openjpa.RuntimeUnenhancedClasses}"/>
-                <entry key="openjpa.jdbc.SynchronizeMappings" value="${rave-shindig.openjpa.jdbc.SynchronizeMappings}"/>
-                <entry key="openjpa.jdbc.MappingDefaults" value="${rave-shindig.openjpa.jdbc.MappingDefaults}"/>
-            </map>
-        </property>
+    <bean id="personService" class="org.apache.rave.opensocial.service.impl.DefaultPersonService">
+        <constructor-arg name="repository" ref="mockPersonRepo" />
     </bean>
 
-    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
-        <property name="url" value="${rave-shindig.dataSource.url}"/>
-        <property name="driverClassName" value="${rave-shindig.dataSource.driver}"/>
-        <property name="username" value="${rave-shindig.dataSource.username}"/>
-        <property name="password" value="${rave-shindig.dataSource.password}"/>
-    </bean>
-
+    <bean id="springBindingModule" class="org.apache.rave.inject.SpringBindingModule" />
+    <!--
     <bean id="oAuthStore" class="org.apache.rave.gadgets.oauth.inject.DefaultOAuthStore">
         <constructor-arg name="defaultCallbackUrl" value="${shindig.signing.global-callback-url}"/>
         <constructor-arg name="pathToPrivateKey" value="${shindig.signing.key-file}"/>
         <constructor-arg name="privateKeyName" value="${shindig.signing.key-name}"/>
-    </bean>
+    </bean>-->
 
 </beans>
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/pom.xml b/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/pom.xml
index 8c19f84..249e214 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/pom.xml
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/pom.xml
@@ -59,6 +59,10 @@
             </exclusions>
         </dependency>
         <dependency>
+            <groupId>org.apache.rave</groupId>
+            <artifactId>rave-jpa</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.apache.shindig</groupId>
             <artifactId>shindig-server</artifactId>
             <type>war</type>
diff --git a/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/src/main/resources/rave-shindig-applicationContext.xml b/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/src/main/resources/rave-shindig-applicationContext.xml
index f3bdbeb..c74f2f1 100644
--- a/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/src/main/resources/rave-shindig-applicationContext.xml
+++ b/rave-providers/rave-opensocial-provider/rave-opensocial-server/rave-shindig/src/main/resources/rave-shindig-applicationContext.xml
@@ -58,7 +58,7 @@
 
     <bean id="entityManagerFactory"
           class="org.apache.rave.persistence.jpa.PopulatedLocalContainerEntityManagerFactory">
-        <property name="persistenceUnitName" value="raveShindigPersistenceUnit"/>
+        <property name="persistenceUnitName" value="ravePersistenceUnit"/>
         <property name="dataSource" ref="dataSource"/>
         <property name="populator" ref="dataSourcePopulator"/>
         <property name="jpaVendorAdapter">
diff --git a/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/W3CWidget.java b/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/W3CWidget.java
index 5d13996..aeb7781 100644
--- a/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/W3CWidget.java
+++ b/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/W3CWidget.java
@@ -19,7 +19,7 @@
 
 package org.apache.rave.provider.w3c.service.impl;
 
-import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 
 /**
  * Extended version of Widget with some additional W3C metadata.
@@ -28,7 +28,7 @@
  * Rave data model classes.
  * 
  */
-public class W3CWidget extends Widget{
+public class W3CWidget extends WidgetImpl {
 	
 	private static final long serialVersionUID = 6211520730435963518L;
 	
diff --git a/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetService.java b/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetService.java
index 9f65a81..a982f31 100644
--- a/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetService.java
+++ b/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetService.java
@@ -66,12 +66,12 @@
         Collection<org.apache.wookie.connector.framework.Widget> widgets = connectorService.getAvailableWidgets().values();
         ArrayList<Widget> raveWidgets = new ArrayList<Widget>();
         for (org.apache.wookie.connector.framework.Widget wookieWidget: widgets){
-            Widget widget = new Widget();
+            Widget widget = new W3CWidget();
             widget.setUrl(wookieWidget.getIdentifier());
             widget.setDescription(wookieWidget.getDescription());
-            widget.setTitle(wookieWidget.getName());
+            widget.setTitle(wookieWidget.getTitle());
             widget.setThumbnailUrl(wookieWidget.getIcon().toString());
-            widget.setAuthor(wookieWidget.getAuthor());
+            //widget.setAuthor(wookieWidget.getAuthor());
             raveWidgets.add(widget);
         }
         return raveWidgets.toArray(new Widget[raveWidgets.size()]);
diff --git a/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java b/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java
index 4a24e19..e7e816c 100644
--- a/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java
+++ b/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java
@@ -100,7 +100,7 @@
         scriptManager.registerScriptBlock(widgetScript, ScriptLocation.AFTER_RAVE, RenderScope.CURRENT_REQUEST, context);
         logger.debug("Gadget Script Data: " + widgetScript);
 
-        return String.format(MARKUP, item.getEntityId());
+        return String.format(MARKUP, item.getId());
     }
 
     /**
@@ -114,7 +114,7 @@
         //
         // For the shared data key we use the RegionWidget entity ID.
         //
-        String sharedDataKey = String.valueOf(item.getEntityId());
+        String sharedDataKey = String.valueOf(item.getId());
 
         //
         // Get the Rave Widget for this regionWidget instance
@@ -150,14 +150,14 @@
         // Construct and return script block
         //
         return String.format(SCRIPT_BLOCK,
-                item.getRegion().getEntityId(),
+                item.getRegion().getId(),
                 WIDGET_TYPE,
-                item.getEntityId(),
+                item.getId(),
                 contextualizedWidget.getUrl(),
                 height,
                 width,
                 item.isCollapsed(),
-                item.getWidget().getEntityId(),
+                item.getWidget().getId(),
                 item.isLocked(),
                 item.isHideChrome());
     }
diff --git a/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetMetadataResolverTest.java b/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetMetadataResolverTest.java
index 729048b..00cf3bf 100644
--- a/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetMetadataResolverTest.java
+++ b/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/service/impl/WookieWidgetMetadataResolverTest.java
@@ -20,6 +20,7 @@
 package org.apache.rave.provider.w3c.service.impl;
 
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.service.WidgetMetadataResolver;
 import org.apache.rave.provider.w3c.repository.W3CWidgetMetadataRepository;
 import org.apache.wookie.connector.framework.WookieConnectorException;
@@ -28,12 +29,8 @@
 
 import java.io.IOException;
 
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
 
 public class WookieWidgetMetadataResolverTest {
     private W3CWidgetMetadataRepository wookieWidgetMetadataRepository;
@@ -52,7 +49,7 @@
         wookieWidgetMetadataRepository = createNiceMock(W3CWidgetMetadataRepository.class);
         widgetMetadataResolver = new WookieWidgetMetadataResolver(widgetService);
         
-        TEST_WIDGET = new Widget();
+        TEST_WIDGET = new WidgetImpl();
         TEST_WIDGET.setTitle("freeder");
         TEST_WIDGET.setUrl("http://wookie.apache.org/widgets/freeder");
         TEST_WIDGET.setDescription("An RSS reader widget optimised for small screens or desktop widgets.");
diff --git a/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java b/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java
index 54283e2..43547dc 100644
--- a/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java
+++ b/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java
@@ -19,19 +19,15 @@
 
 package org.apache.rave.provider.w3c.web.renderer;
 
-import static org.easymock.EasyMock.createNiceMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
 import org.apache.rave.exception.NotSupportedException;
 import org.apache.rave.portal.model.Region;
 import org.apache.rave.portal.model.RegionWidget;
 import org.apache.rave.portal.model.User;
 import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.impl.RegionImpl;
+import org.apache.rave.portal.model.impl.RegionWidgetImpl;
+import org.apache.rave.portal.model.impl.UserImpl;
+import org.apache.rave.portal.model.impl.WidgetImpl;
 import org.apache.rave.portal.service.UserService;
 import org.apache.rave.portal.service.WidgetProviderService;
 import org.apache.rave.portal.web.renderer.Renderer;
@@ -42,6 +38,12 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
 /*
 */
 public class W3cWidgetRendererTest {
@@ -56,6 +58,7 @@
 
     @Before
     public void setup() {
+
         renderContext = new RenderContext();
         wookieService = createNiceMock(WidgetProviderService.class);
         userService = createNiceMock(UserService.class);
@@ -70,23 +73,23 @@
 
     @Test
     public void render_valid() {
-        User user = new User(9999L, "testUser");
+        User user = new UserImpl(9999L, "testUser");
         expect(userService.getAuthenticatedUser()).andReturn(user);
         replay(userService);
         
         W3CWidget w = new W3CWidget();
         w.setType(Constants.WIDGET_TYPE);
         w.setUrl("http://example.com/widgets/1");
-        Region region = new Region(1L);
-        RegionWidget rw = new RegionWidget();
-        rw.setEntityId(1L);
+        Region region = new RegionImpl(1L);
+        RegionWidget rw = new RegionWidgetImpl();
+        rw.setId(1L);
         rw.setWidget(w);
         rw.setRegion(region);
 
         W3CWidget wookieWidget = new W3CWidget();
         wookieWidget.setUrl(VALID_WIDGET_INSTANCE_URL);
 
-        expect(wookieService.getWidget(user, rw.getEntityId().toString(), w)).andReturn(wookieWidget);
+        expect(wookieService.getWidget(eq(user), eq(rw.getId().toString()), isA(Widget.class))).andReturn(wookieWidget);
         replay(wookieService);
 
         String placeholder = renderer.render(rw, renderContext);
@@ -95,11 +98,11 @@
 
     @Test(expected = NotSupportedException.class)
     public void render_invalid() {
-        Widget w = new Widget();
+        Widget w = new WidgetImpl();
         w.setType("NONE");
         w.setUrl(VALID_WIDGET_URL);
-        RegionWidget rw = new RegionWidget();
-        rw.setEntityId(1L);
+        RegionWidget rw = new RegionWidgetImpl();
+        rw.setId(1L);
         rw.setWidget(w);
 
         RenderContext renderContext = createNiceMock(RenderContext.class);