--- a
+++ b/OSSEval/OpenSourceProject/doap.py
@@ -0,0 +1,244 @@
+# This Source Code Form of OSSEval is subject to the terms of the GNU AFFERO
+# GENERAL PUBLIC LICENSE, v. 3.0. If a copy of the AGPL was not
+# distributed with this file, You can obtain one at http://www.gnu.org/licenses/agpl.txt
+#
+# OSSeval is powered by the SOS Open Source AGPL edition.
+#  The AGPL requires that you do not remove the SOS Open Source attribution and copyright 
+#  notices from the user interface (see section 5.d below).
+
+# OSSEval Copyright 2014 Bitergium SLL
+# SOS Open Source Copyright 2012 Roberto Galoppini
+# Author: Davide Galletti 
+
+
+
+from utils import Configuration, Forges
+
+from django.db import connections
+
+class Apache():
+
+    @staticmethod
+    def search(name):
+        project_list = []
+        cursor = connections['flossmole'].cursor()
+        parameters = { 'limit': Configuration.max_number_of_records } 
+        cursor.execute("SELECT idDoap, Name, Shortdesc, Description, Homepage FROM apache_doap WHERE LOWER(name) LIKE '%%" + name.lower() + "%%' LIMIT %(limit)s", parameters)
+        results = cursor.fetchall()
+        for record in results:
+            fp = FlossmoleProject()
+            fp.id = record[0]
+            fp.id_forge = Forges.FSF
+            fp.datasource_id = record[1]
+            fp.name = record[2]
+            fp.description = record[3]
+            project_list.append(fp)
+        return project_list
+
+    @staticmethod
+    def getProjectInfo(project_identifier):
+        info = {}
+        cursor = connections['flossmole'].cursor()
+        cursor.execute("SELECT max(datasource_id) FROM fsf_projects")
+        row = cursor.fetchone()
+        datasource_id = row[0]
+        parameters = { 'datasource_id': datasource_id, 'project_identifier': project_identifier } 
+        cursor.execute("SELECT proj_long_name, desc_long, url, real_url, released_on, proj_num FROM fsf_projects WHERE proj_unixname=%(project_identifier)s and datasource_id=%(datasource_id)s", parameters)
+        result = cursor.fetchone()
+        info['name'] = result[0]
+        info['desc_long'] = result[1]
+        info['url'] = result[2]
+        info['real_url'] = result[3]
+        info['released_on'] = result[4]
+        proj_num = result[5]
+        
+        info['licenses'] = []
+        parameters = { 'datasource_id': datasource_id, 'proj_num': proj_num }
+        cursor.execute("SELECT license FROM fsf_project_licenses WHERE proj_num=%(proj_num)s  and datasource_id=%(datasource_id)s", parameters)
+        results = cursor.fetchall()
+        for record in results:
+            info['licenses'].append(record[0])
+
+        info['developers'] = []
+        cursor.execute("SELECT person_name, role, email FROM fsf_developer_projects WHERE proj_num=%(proj_num)s  and datasource_id=%(datasource_id)s", parameters)
+        results = cursor.fetchall()
+        for record in results:
+            developer = {}
+            developer['person_name'] = record[0]
+            developer['role'] = record[1]
+            developer['email'] = record[2]
+            info['developers'].append(developer)
+
+        info['categories'] = []
+        parameters = { 'datasource_id': datasource_id, 'proj_num': proj_num }
+        cursor.execute("SELECT project_category_title FROM fsf_project_categories WHERE proj_num=%(proj_num)s  and datasource_id=%(datasource_id)s", parameters)
+        results = cursor.fetchall()
+        for record in results:
+            info['categories'].append(record[0])
+        
+        info['requirements'] = []
+        cursor.execute("SELECT requirement, requirement_type FROM fsf_project_requirements WHERE proj_num=%(proj_num)s  and datasource_id=%(datasource_id)s", parameters)
+        results = cursor.fetchall()
+        for record in results:
+            requirement = {}
+            requirement['requirement'] = record[0]
+            requirement['requirement_type'] = record[1]
+            info['requirements'].append(requirement)
+
+        return info
+
+
+class FoafPerson:
+    def __init__(self, firstName, lastName, login = ""):
+        # see issue 867 for details: http://markosproject.berlios.de/mantis/view.php?id=867
+        # Apache data sometimes is wrongly encoded: 'utf8' codec can't decode byte 0xfc in position 9: invalid start byte
+        try:
+            foo = firstName.decode('utf-8')
+            self.firstName = firstName
+        except:
+            self.firstName = StringHelper.removeNonAscii(firstName)
+        self.lastName = lastName
+        self.login = login
+
+class DoapVersion:
+    def __init__(self):
+        self.os = []
+    
+class DoapRepository:
+    def __init__(self, parent):
+        self.parent_id_doap = parent.idDoap
+        
+class DoapProject(object):
+    """
+    Class with the information in the DOAP format
+    """
+    def __init__(self):
+        self._idDoap = None
+
+    @property
+    def idDoap(self):
+        return self._idDoap
+
+    @idDoap.setter
+    def idDoap(self, value):
+        self._idDoap = value
+        if hasattr(self, "svn_repository") and (not (self.svn_repository is None)):
+            self.svn_repository.parent_id_doap = self._idDoap
+        if hasattr(self, "hg_repository") and (not (self.hg_repository is None)):
+            self.hg_repository.parent_id_doap = self._idDoap
+        if hasattr(self, "darcs_repository") and (not (self.darcs_repository is None)):
+            self.darcs_repository.parent_id_doap = self._idDoap
+        if hasattr(self, "bzr_repository") and (not (self.bzr_repository is None)):
+            self.bzr_repository.parent_id_doap = self._idDoap
+        if hasattr(self, "arch_repository") and (not (self.arch_repository is None)):
+            self.arch_repository.parent_id_doap = self._idDoap
+        if hasattr(self, "bk_repository") and (not (self.bk_repository is None)):
+            self.bk_repository.parent_id_doap = self._idDoap
+        if hasattr(self, "cvs_repository") and (not (self.cvs_repository is None)):
+            self.cvs_repository.parent_id_doap = self._idDoap
+        if hasattr(self, "git_repository") and (not (self.git_repository is None)):
+            self.git_repository.parent_id_doap = self._idDoap
+        
+
+    def load_from_db(self, idDoap):
+        self.idDoap = idDoap
+        try:
+            # expression for modified, modified_release is due to a bug in mysqldb for BIT data type
+            cursor = CrawlerDatabase.execute_cursor("SELECT name, shortdesc, description, homepage, created, mailing_list, download_page, bug_database, platform, service_endpoint, audience, blog,  IF(modified=1,1,0) as modified, old_homepage, category, license, download_mirror, wiki, programming_language, os, language, idDWBatch, idProject, IF(modified_release=1,1,0) as modified_release FROM Doap WHERE idDoap="+str(idDoap))
+            result = cursor.fetchone()
+            #for each project in the batch
+            if (result is None):
+                #throw
+                pass
+            else:
+                self.name = result[0]
+                self.shortdesc = result[1]
+                self.description = result[2]
+                self.homepage = result[3]
+                self.created = str(result[4])
+                self.mailing_list = result[5]
+                self.download_page = result[6]
+                self.bug_database = result[7]
+                self.platform = result[8]
+                self.service_endpoint = result[9]
+                self.audience = result[10]
+                self.blog = result[11]
+                self.modified = True if result[12] == b'\x00' else False
+                self.modified_release = True if result[23] == b'\x00' else False
+                self.old_homepage = StringList().load_base64(result[13]).plain
+                self.category = StringList().load_base64(result[14]).plain
+                self.license = StringList().load_base64(result[15]).plain
+                self.download_mirror = StringList().load_base64(result[16]).plain
+                self.wiki = StringList().load_base64(result[17]).plain
+                self.programming_language = StringList().load_base64(result[18]).plain
+                self.os = StringList().load_base64(result[19]).plain
+                self.language = StringList().load_base64(result[20]).plain
+                self.idDWBatch = result[21]
+                self.idProject = result[22] 
+                #DoapVersion Table
+                self.release = []
+                cur = CrawlerDatabase.execute_cursor("SELECT platform, revision, file_release, created, name FROM DoapVersion WHERE idDoap=" + str(self.idDoap))
+                results = cur.fetchall()
+                for record in results:
+                    dv = DoapVersion()
+                    dv.name = record[4]
+                    dv.created = str(record[3])
+                    dv.revision = record[1]
+                    dv.platform = record[0]
+                    dv.file_release = StringList().load_base64(record[2]).plain  
+                    self.release.append(dv)
+                #DoapRepository Table 
+                cur = CrawlerDatabase.execute_cursor("SELECT browse, anon_root, location, type FROM DoapRepository WHERE idDoap=" + str(self.idDoap))
+                results = cur.fetchall()
+                for record in results:
+                    dr = DoapRepository(self)
+                    dr.browse = record[0]
+                    dr.anon_root = record[1]
+                    dr.location = record[2]
+                    dr.type = record[3]
+                    if dr.type == 'svn':
+                        self.svn_repository = dr
+                    if dr.type == 'bk':
+                        self.bk_repository = dr
+                    if dr.type == 'cvs':
+                        pass
+                    #PATCH doapfiend adds a cvs even if it is not there                        self.cvs_repository = dr
+                    if dr.type == 'arch':
+                        self.arch_repository = dr
+                    if dr.type == 'bzr':
+                        self.bzr_repository = dr
+                    if dr.type == 'git':
+                        self.git_repository = dr
+                    if dr.type == 'hg':
+                        self.hg_repository = dr
+                    if dr.type == 'darcs':
+                        self.darcs_repository = dr
+
+                self.maintainer = []
+                self.developer = []
+                self.documenter = []
+                self.helper = []
+                self.tester = []
+                self.translator = []
+                parameters = {
+                              'idDoapProject': idDoap
+                              }
+                cur = CrawlerDatabase.execute_cursor("SELECT fp.firstName, fp.lastName, fp.login, dpfp.idDoapRole FROM FoafPerson fp JOIN DoapProjectFoafPerson dpfp on fp.idFoafPerson=dpfp.idFoafPerson WHERE idDoapProject=%(idDoapProject)s", parameters)
+                results = cur.fetchall()
+                for record in results:
+                    fp = FoafPerson(record[0], record[1], record[2])
+                    idDoapRole = record[3]
+                    if idDoapRole == 1:
+                        self.maintainer.append(fp)
+                    elif idDoapRole == 2:
+                        self.developer.append(fp)
+                    elif idDoapRole == 3:
+                        self.documenter.append(fp)
+                    elif idDoapRole == 4:
+                        self.tester.append(fp)
+                    elif idDoapRole == 5:
+                        self.translator.append(fp)
+                    elif idDoapRole == 6:
+                        self.helper.append(fp)
+        except Exception, e:
+            Logger.error(str(e))