diff --git a/.buildpath b/.buildpath
index e9e2cb4..a59af60 100644
--- a/.buildpath
+++ b/.buildpath
@@ -1,6 +1,7 @@
+
diff --git a/.settings/org.eclipse.php.ui.prefs b/.settings/org.eclipse.php.ui.prefs
new file mode 100644
index 0000000..9a3362f
--- /dev/null
+++ b/.settings/org.eclipse.php.ui.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.php.ui.text.custom_code_templates=
diff --git a/src/admin/clubs.php b/src/admin/clubs.php
index f52ed19..c82b2d7 100644
--- a/src/admin/clubs.php
+++ b/src/admin/clubs.php
@@ -8,6 +8,8 @@ defined('_JEXEC') or die;
JLoader::discover('Clubs', JPATH_ROOT . '/administrator/components/com_clubs/mymodels');
JLoader::registerPrefix('AbstractClubs', JPATH_ROOT . '/administrator/components/com_clubs/abstract');
+JLoader::registerPrefix('AbstractCommonClubs', JPATH_ROOT . '/administrator/components/com_clubs/common/abstract');
+// JLoader::registerPrefix('ClubsHelper', JPATH_ROOT . '/administrator/components/com_clubs/common/helper');
$controller = BaseController::getInstance("Clubs");
$input = Factory::getApplication()->input;
diff --git a/src/admin/common/abstract/model.php b/src/admin/common/abstract/model.php
new file mode 100644
index 0000000..3c7bfca
--- /dev/null
+++ b/src/admin/common/abstract/model.php
@@ -0,0 +1,37 @@
+id;
+ }
+
+ public function setId($id)
+ {
+ $this->id = $id;
+ }
+
+ private $values = null;
+
+ protected function getValues()
+ {
+ if(is_null($this->values))
+ // FIXME fetch cache
+ return;
+
+ return $this->values;
+ }
+
+ public function setValues($values)
+ {
+ $this->values = $values;
+ }
+
+}
diff --git a/src/admin/common/abstract/modelfactory.php b/src/admin/common/abstract/modelfactory.php
new file mode 100644
index 0000000..8b8b8cb
--- /dev/null
+++ b/src/admin/common/abstract/modelfactory.php
@@ -0,0 +1,111 @@
+array('col'=>'Name', type=>'string'),
+ * 'size'=>array('col'=>'area', type=>'int')
+ * )
+ *
+ * The inner arrays contain the following entries:
+ * - col: The name of the column in the database. Mandatory.
+ * - type: The type of the column. If nothing is specified, string is assumed.
+ * - string
+ * - int
+ * - float
+ * - ref
+ * - ref: (only with type='ref') The name of the class that is referenced
+ */
+ protected abstract function getAttributes();
+
+ private $attributes = null;
+ private function fetchAttributes()
+ {
+ if($this->attributes === null)
+ $this->attributes = $this->getAttributes();
+
+ return $this->attributes;
+ }
+
+ protected abstract function getTableName();
+ protected abstract function getClassName();
+
+ /**
+ *
+ * @param string $condition
+ * @return array
+ */
+ protected function loadElements($condition = null)
+ {
+ $db = Factory::getDbo();
+ $q = $db->getQuery(true);
+
+// $columns = array_map(function($arr) use ($q){ return $q->qn('main' . $arr['col']); }, $this->fetchAttributes());
+ $columns = array();
+ foreach($this->fetchAttributes() as $k=>$v)
+ {
+ $columns[] = $q->qn('main' . $v['col'], $k);
+ }
+
+ $q->select('main.id')->select($columns);
+ $q->from($this->getTableName(), 'main');
+
+ // TODO Joins
+
+ if($condition !== null)
+ $q->where($condition);
+
+ $db->setQuery($q);
+ $db->execute();
+
+ $it = $db->getIterator();
+ $ret = array();
+ while($it->valid())
+ {
+ $row = $it->current();
+ $ret[] = $this->generateObject($row);
+ $it->next();
+ }
+
+ return $ret;
+ }
+
+ /**
+ *
+ * @param int $id
+ */
+ protected function loadById($id) {
+ $arr = $this->loadElements("main.id = " . ((int)$id) );
+ if(sizeof($arr) == 0)
+ throw new ElementNotFoundException();
+
+ return $arr[0];
+ }
+
+ protected function generateObject($row)
+ {
+ $name = $this->getClassName();
+ $obj = new $name();
+
+ $obj->setId($row['id']);
+
+ unset($row['id']);
+ $obj->setValues($row);
+
+ return $obj;
+ }
+}