diff -Naur pacman-lib.old/lib/libalpm/alpm.c pacman-lib/lib/libalpm/alpm.c
--- pacman-lib.old/lib/libalpm/alpm.c	2007-03-06 02:21:41.000000000 +0100
+++ pacman-lib/lib/libalpm/alpm.c	2007-03-07 23:11:43.000000000 +0100
@@ -239,6 +239,25 @@
 	return(0);
 }
 
+/** Repair a local database: creates .brokendeps, .groups, .providers, .conflicts
+ * TODO: this should return a list to brokendeps, so pacman could offer the user to fix them
+ * @param db pointer to the local database (redundant)
+ * @return 0 on success, 1 on error
+ */
+int SYMEXPORT alpm_db_repair(pmdb_t *db)
+{
+	ALPM_LOG_FUNC;
+
+	/* Sanity checks */
+	ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+	ASSERT(db == handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+	/* Do not repair a database if a transaction is on-going */
+	ASSERT(handle->trans == NULL, RET_ERR(PM_ERR_TRANS_NOT_NULL, -1));
+
+	return(_alpm_db_repair(db));
+}
+
+
 /** Update a package database
  * @param force if true, then forces the update, otherwise update only in case
  * the database isn't up to date
diff -Naur pacman-lib.old/lib/libalpm/alpm.h pacman-lib/lib/libalpm/alpm.h
--- pacman-lib.old/lib/libalpm/alpm.h	2007-03-07 08:45:30.000000000 +0100
+++ pacman-lib/lib/libalpm/alpm.h	2007-03-07 23:09:56.000000000 +0100
@@ -171,6 +171,8 @@
 
 int alpm_db_setserver(pmdb_t *db, const char *url);
 
+int alpm_db_repair(pmdb_t *db);
+
 int alpm_db_update(int level, pmdb_t *db);
 
 pmpkg_t *alpm_db_get_pkg(pmdb_t *db, const char *name);
diff -Naur pacman-lib.old/lib/libalpm/be_files.c pacman-lib/lib/libalpm/be_files.c
--- pacman-lib.old/lib/libalpm/be_files.c	2007-03-05 23:13:33.000000000 +0100
+++ pacman-lib/lib/libalpm/be_files.c	2007-03-08 23:55:26.000000000 +0100
@@ -47,6 +47,7 @@
 #include "error.h"
 #include "handle.h"
 #include "package.h"
+#include "cache.h"
 
 
 /* This function is used to convert the downloaded db file to the proper backend
@@ -109,6 +110,75 @@
 	rewinddir(db->handle);
 }
 
+int _alpm_db_repair(pmdb_t *db)
+/*TODO: safety checks*/
+{
+	char path[PATH_MAX+1];
+	char newpath[PATH_MAX+1];
+	alpm_list_t *i, *j;
+	pmpkg_t *pkg;
+
+	ALPM_LOG_FUNC;
+
+	//in alpm.c we checked that db==handle->db_local
+	if(db == NULL) {
+		RET_ERR(PM_ERR_DB_NULL, -1);
+	}
+
+	_alpm_log(PM_LOG_DEBUG, _("repairing local database"));
+
+	snprintf(path, PATH_MAX, "%s/.brokendeps", db->path);
+	if(_alpm_rmrf(path)) {
+		return(-1);
+	}
+	_alpm_makepath(path);
+	snprintf(path, PATH_MAX, "%s/.groups", db->path);
+	if(_alpm_rmrf(path)) {
+		return(-1);
+	}
+	_alpm_makepath(path);
+	snprintf(path, PATH_MAX, "%s/.providers", db->path);
+	if(_alpm_rmrf(path)) {
+		return(-1);
+	}
+	_alpm_makepath(path);
+	snprintf(path, PATH_MAX, "%s/.conflicts", db->path);
+	if(_alpm_rmrf(path)) {
+		return(-1);
+	}
+	_alpm_makepath(path);
+	_alpm_log(PM_LOG_DEBUG, _("old dotdirs removed"));
+	
+	for(i=_alpm_db_get_pkgcache(db); i; i=i->next) {
+		pkg=i->data; 
+		_alpm_db_read(db,pkg,INFRQ_ALL);
+		for(j=alpm_pkg_get_groups(pkg); j; j=j->next) {
+			snprintf(path, PATH_MAX, "%s/.groups/%s", db->path, j->data);
+			_alpm_makepath(path);	
+			snprintf(path, PATH_MAX, "%s%s-%s", db->path, pkg->name, pkg->version);
+			snprintf(newpath, PATH_MAX, "%s/.groups/%s/%s-%s", db->path, j->data, pkg->name, pkg->version);
+			symlink(path,newpath);
+		}	
+		if(alpm_list_count(alpm_pkg_get_provides(pkg))) {
+			snprintf(path, PATH_MAX, "%s%s-%s", db->path, pkg->name, pkg->version);
+			snprintf(newpath, PATH_MAX, "%s/.providers/%s-%s", db->path, pkg->name, pkg->version);
+			symlink(path,newpath);
+		}		
+		if(alpm_list_count(alpm_pkg_get_conflicts(pkg))) {
+			snprintf(path, PATH_MAX, "%s%s-%s", db->path, pkg->name, pkg->version);
+			snprintf(newpath, PATH_MAX, "%s/.conflicts/%s-%s", db->path, pkg->name, pkg->version);
+			symlink(path,newpath);
+		}
+	//Now we can use our newly created dotdirs
+	}		
+	
+	_alpm_db_free_pkgcache(db); //just to be sure, this is a rarely used function
+	_alpm_log(PM_LOG_DEBUG, _("repair successfully finished"));
+	db->groups=1;
+	return(0);
+}
+
+
 pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
 {
 	struct dirent *ent = NULL;
@@ -134,7 +204,7 @@
 			/* search for a specific package (by name only) */
 			rewinddir(db->handle);
 			while(!found && (ent = readdir(db->handle)) != NULL) {
-				if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+				if(ent->d_name[0]=='.') {
 					continue;
 				}
 				/* stat the entry, make sure it's a directory */
@@ -165,7 +235,7 @@
 				if(ent == NULL) {
 					return(NULL);
 				}
-				if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
+				if(ent->d_name[0]=='.') {
 					isdir = 0;
 					continue;
 				}
@@ -227,7 +297,7 @@
 		return(-1);
 	}
 
-	if(info->infolevel & inforeq) {
+	if(!(~(info->infolevel) & inforeq)) {
 		/* already loaded this info, do nothing */
 		return(0);
 	}
@@ -766,4 +836,44 @@
 	return(0);
 }
 
+/* Speed tuned version of _alpm_db_load_grpcache*/
+int _alpm_be_load_grpcache(pmdb_t *db)
+{
+	pmdb_t fakedb;
+	strcpy(fakedb.treename, "fakedb");
+
+	pmpkg_t *pkg;
+
+	char path[PATH_MAX+1];
+	sprintf(path, "%s/.groups/", db->path);
+	DIR *dirp=opendir(path);
+	if (dirp == NULL) RET_ERR(PM_ERR_DB_OPEN, -1);
+	struct dirent *dp;
+
+	_alpm_db_free_grpcache(db);
+	_alpm_log(PM_LOG_DEBUG, _("old grpcache freed"));
+
+	for(dp = readdir(dirp); dp != NULL ; dp = readdir(dirp)) {
+		if(dp->d_ino && dp->d_name[0] != '.') {
+			pmgrp_t *grp = _alpm_grp_new();
+			strncpy(grp->name, dp->d_name, GRP_NAME_LEN);
+			grp->name[GRP_NAME_LEN-1] = '\0';
+			//we are tricky here : we create a fake db with our path
+			sprintf(path, "%s/.groups/%s", db->path, dp->d_name);
+			fakedb.path=path;
+			if(_alpm_db_open(&fakedb)) return -1;
+			_alpm_log(PM_LOG_DEBUG, _("scanning: %s, %s"), dp->d_name, fakedb.treename);
+
+			while((pkg = _alpm_db_scan(&fakedb, NULL)) != NULL) {
+				grp->packages = alpm_list_add_sorted(grp->packages, strdup(alpm_pkg_get_name(pkg)), _alpm_grp_cmp);
+				_alpm_pkg_free(pkg);
+			}
+			db->grpcache = alpm_list_add_sorted(db->grpcache, grp, _alpm_grp_cmp);
+			_alpm_db_close(&fakedb);
+		}
+	}
+	closedir(dirp);
+	
+
+}
 /* vim: set ts=2 sw=2 noet: */
diff -Naur pacman-lib.old/lib/libalpm/cache.c pacman-lib/lib/libalpm/cache.c
--- pacman-lib.old/lib/libalpm/cache.c	2007-03-05 23:13:33.000000000 +0100
+++ pacman-lib/lib/libalpm/cache.c	2007-03-08 23:39:02.000000000 +0100
@@ -194,12 +194,18 @@
 		return(-1);
 	}
 
+	_alpm_log(PM_LOG_DEBUG, _("loading group cache for repository '%s'"), db->treename);
+
+	if(db->groups) //can we use the tuned version?
+	return (_alpm_be_load_grpcache(db));
+
+	else //old method
+ {
+
 	if(db->pkgcache == NULL) {
 		_alpm_db_load_pkgcache(db);
 	}
 
-	_alpm_log(PM_LOG_DEBUG, _("loading group cache for repository '%s'"), db->treename);
-
 	for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
 		alpm_list_t *i;
 		pmpkg_t *pkg = lp->data;
@@ -213,7 +219,7 @@
 				grp->packages = alpm_list_add_sorted(grp->packages,
 																						 /* gross signature forces us to
 																							* discard const */
-																						 (void *)alpm_pkg_get_name(pkg),
+																						 strdup(alpm_pkg_get_name(pkg)),
 																						 _alpm_grp_cmp);
 				db->grpcache = alpm_list_add_sorted(db->grpcache, grp, _alpm_grp_cmp);
 			} else {
@@ -225,7 +231,7 @@
 					if(strcmp(grp->name, i->data) == 0) {
 						const char *pkgname = alpm_pkg_get_name(pkg);
 						if(!alpm_list_find_str(grp->packages, pkgname)) {
-							grp->packages = alpm_list_add_sorted(grp->packages, (void *)pkgname, _alpm_grp_cmp);
+							grp->packages = alpm_list_add_sorted(grp->packages, strdup(pkgname), _alpm_grp_cmp);
 						}
 					}
 				}
@@ -234,6 +240,7 @@
 	}
 
 	return(0);
+ }
 }
 
 void _alpm_db_free_grpcache(pmdb_t *db)
@@ -246,13 +253,7 @@
 		return;
 	}
 
-	for(lg = db->grpcache; lg; lg = lg->next) {
-		pmgrp_t *grp = lg->data;
-
-		FREELISTPTR(grp->packages);
-		FREEGRP(lg->data);
-	}
-	FREELIST(db->grpcache);
+	FREELISTGRPS(db->grpcache);
 }
 
 alpm_list_t *_alpm_db_get_grpcache(pmdb_t *db)
diff -Naur pacman-lib.old/lib/libalpm/db.c pacman-lib/lib/libalpm/db.c
--- pacman-lib.old/lib/libalpm/db.c	2007-03-05 23:13:34.000000000 +0100
+++ pacman-lib/lib/libalpm/db.c	2007-03-08 20:40:39.000000000 +0100
@@ -56,7 +56,9 @@
 pmdb_t *_alpm_db_new(const char *root, const char *dbpath, const char *treename)
 {
 	pmdb_t *db;
-
+	struct stat buf;
+	char path[PATH_MAX+1];
+	
 	ALPM_LOG_FUNC;
 
 	db = calloc(1, sizeof(pmdb_t));
@@ -77,6 +79,9 @@
 
 	STRNCPY(db->treename, treename, PATH_MAX);
 
+	sprintf(path, "%s/%s", db->path, ".groups");
+	db->groups = (!stat(path, &buf) && S_ISDIR(buf.st_mode));
+	
 	return(db);
 }
 
diff -Naur pacman-lib.old/lib/libalpm/db.h pacman-lib/lib/libalpm/db.h
--- pacman-lib.old/lib/libalpm/db.h	2007-03-03 09:13:59.000000000 +0100
+++ pacman-lib/lib/libalpm/db.h	2007-03-08 22:46:45.000000000 +0100
@@ -43,6 +43,10 @@
 	void *handle;
 	alpm_list_t *pkgcache;
 	alpm_list_t *grpcache;
+	int groups; //for compatibility reasons: true for .groups method
+	alpm_list_t *conflicts;
+	alpm_list_t *provides;
+	alpm_list_t *brokens;
 	alpm_list_t *servers;
 };
 
@@ -58,12 +62,14 @@
 int _alpm_db_open(pmdb_t *db);
 void _alpm_db_close(pmdb_t *db);
 void _alpm_db_rewind(pmdb_t *db);
+int _alpm_db_repair(pmdb_t *db);
 pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target);
 int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
 int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq);
 int _alpm_db_remove(pmdb_t *db, pmpkg_t *info);
 int _alpm_db_getlastupdate(pmdb_t *db, char *ts);
 int _alpm_db_setlastupdate(pmdb_t *db, char *ts);
+int _alpm_be_load_grpcache(pmdb_t *db);
 
 #endif /* _ALPM_DB_H */
 
diff -Naur pacman-lib.old/lib/libalpm/util.c pacman-lib/lib/libalpm/util.c
--- pacman-lib.old/lib/libalpm/util.c	2007-03-05 23:13:34.000000000 +0100
+++ pacman-lib/lib/libalpm/util.c	2007-03-08 17:06:27.000000000 +0100
@@ -312,8 +312,8 @@
 	char name[PATH_MAX];
   struct stat st;
 
-	if(stat(path, &st) == 0) {
-		if(S_ISREG(st.st_mode)) {
+	if(lstat(path, &st) == 0) {
+		if(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
 			if(!unlink(path)) {
 				return(0);
 			} else {
diff -Naur pacman-lib.old/src/pacman/conf.h pacman-lib/src/pacman/conf.h
--- pacman-lib.old/src/pacman/conf.h	2007-03-06 02:21:42.000000000 +0100
+++ pacman-lib/src/pacman/conf.h	2007-03-07 19:40:08.000000000 +0100
@@ -54,6 +54,7 @@
 	pmtransflag_t flags;
 	unsigned short noask;
 	unsigned int ask;
+	unsigned short op_repair;
 } config_t;
 
 #define FREECONF(p) do { if(p) { config_free(p); p = NULL; } } while(0)
diff -Naur pacman-lib.old/src/pacman/pacman.c pacman-lib/src/pacman/pacman.c
--- pacman-lib.old/src/pacman/pacman.c	2007-03-05 23:13:35.000000000 +0100
+++ pacman-lib/src/pacman/pacman.c	2007-03-07 23:22:05.000000000 +0100
@@ -158,6 +158,7 @@
 		printf(_("  -r, --root <path>    set an alternate installation root\n"));
 		printf(_("  -b, --dbpath <path>  set an alternate database location\n"));
 		printf(_("      --cachedir <dir> set an alternate package cache location\n"));
+		printf(_("      --repair         check and repair the consistency of the local database\n"));	
 	}
 }
 
@@ -260,6 +261,7 @@
 		{"noscriptlet", no_argument,      0, 1005},
 		{"ask",        required_argument, 0, 1006},
 		{"cachedir",   required_argument, 0, 1007},
+		{"repair",     no_argument,	  0, 1008},		
 		{0, 0, 0, 0}
 	};
 	struct stat st;
@@ -316,6 +318,7 @@
 				}
 				alpm_option_set_cachedir(optarg);
 				break;
+			case 1008: config->op_repair = 1; break;
 			case 'A': config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_ADD); break;
 			case 'F':
 				config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_UPGRADE);
@@ -480,7 +483,8 @@
 					(config->op_s_search || config->group || config->op_q_list || config->op_q_info
 					 || config->flags & PM_TRANS_FLAG_PRINTURIS))
 				 || (config->op == PM_OP_DEPTEST && config->op_d_resolve)
-				 || (strcmp(alpm_option_get_root(), PM_ROOT) != 0)) {
+				 || (strcmp(alpm_option_get_root(), PM_ROOT) != 0)
+				 || config->op_repair) {
 				/* special case: PM_OP_SYNC can be used w/ config->op_s_search by any user */
 				/* special case: ignore root user check if -r is specified, fall back on
 				 * normal FS checking */
@@ -521,13 +525,19 @@
 		cleanup(1);
 	}
 
+	/* Repair local db if requested */
+	if(config->op_repair && alpm_db_repair(db_local)){
+		ERR(NL, _("could not repair 'local' database (%s)\n"), alpm_strerror(pm_errno));
+		cleanup(1);
+	}
+	
 	if(alpm_list_count(pm_targets) == 0 && !(config->op == PM_OP_QUERY || (config->op == PM_OP_SYNC
 	   && (config->op_s_sync || config->op_s_upgrade || config->op_s_clean || config->group 
-	   || config->op_q_list)))) {
+	   || config->op_q_list))) && !config->op_repair) {
 		ERR(NL, _("no targets specified (use -h for help)\n"));
 		cleanup(1);
 	}
-
+	
 	/* start the requested operation */
 	switch(config->op) {
 		case PM_OP_ADD:     ret = pacman_add(pm_targets);     break;
