Merge remote-tracking branch 'aosp/upstream-master' into mymerge
diff --git a/checkpolicy/Android.mk b/checkpolicy/Android.mk
index 09ca2ac..bcaa36f 100644
--- a/checkpolicy/Android.mk
+++ b/checkpolicy/Android.mk
@@ -11,7 +11,6 @@
 common_cflags := \
 	-Wall -Wshadow -O2 \
 	-pipe -fno-strict-aliasing \
-	-Wno-return-type
 
 ifeq ($(HOST_OS),darwin)
 common_cflags += -DDARWIN
diff --git a/checkpolicy/ChangeLog b/checkpolicy/ChangeLog
index daa1bbd..1062cb0 100644
--- a/checkpolicy/ChangeLog
+++ b/checkpolicy/ChangeLog
@@ -1,3 +1,8 @@
+	* Add neverallow support for ioctl extended permissions, from Jeff Vander Stoep.
+	* fix double free on name-based type transitions, from Stephen Smalley.
+	* switch operations to extended perms, from Jeff Vander Stoep.
+	* policy_define.c: fix compiler warnings, from Nick Kralevich.
+	* Remove uses of -Wno-return-type, from Dan Albert.
 	* Fix -Wreturn-type issues, from Dan Albert.
 	* dispol: display operations as ranges, from Jeff Vander Stoep.
 	* dispol: Extend to display operations, from Stephen Smalley.
diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
index 093bded..ee20fea 100644
--- a/checkpolicy/policy_define.c
+++ b/checkpolicy/policy_define.c
@@ -1521,7 +1521,8 @@
 	ebitmap_node_t *node;
 	avrule_t *avrule;
 	class_perm_node_t *perm;
-	int i, add = 1;
+	uint32_t i;
+	int add = 1;
 
 	avrule = malloc(sizeof(avrule_t));
 	if (!avrule) {
@@ -1728,32 +1729,27 @@
 	return sl;
 }
 
-#define operation_perm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
-#define operation_perm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f)))
-#define operation_perm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f)))
-
-typedef struct av_operations_range {
+typedef struct av_ioctl_range {
 	uint16_t low;
 	uint16_t high;
-} av_operations_range_t;
+} av_ioctl_range_t;
 
-struct av_operations_range_list {
+struct av_ioctl_range_list {
 	uint8_t omit;
-	av_operations_range_t range;
-	struct av_operations_range_list *next;
+	av_ioctl_range_t range;
+	struct av_ioctl_range_list *next;
 };
 
-int avrule_sort_operations(
-		struct av_operations_range_list **rangehead)
+int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead)
 {
-	struct av_operations_range_list *r, *r2, *sorted, *sortedhead = NULL;
+	struct av_ioctl_range_list *r, *r2, *sorted, *sortedhead = NULL;
 
 	/* order list by range.low */
 	for (r = *rangehead; r != NULL; r = r->next) {
-		sorted = malloc(sizeof(struct av_operations_range_list));
+		sorted = malloc(sizeof(struct av_ioctl_range_list));
 		if (sorted == NULL)
 			goto error;
-		memcpy(sorted, r, sizeof(struct av_operations_range_list));
+		memcpy(sorted, r, sizeof(struct av_ioctl_range_list));
 		sorted->next = NULL;
 		if (sortedhead == NULL) {
 			sortedhead = sorted;
@@ -1792,9 +1788,9 @@
 	return -1;
 }
 
-int avrule_merge_operations(struct av_operations_range_list **rangehead)
+int avrule_merge_ioctls(struct av_ioctl_range_list **rangehead)
 {
-	struct av_operations_range_list *r, *tmp;
+	struct av_ioctl_range_list *r, *tmp;
 	r = *rangehead;
 	while (r != NULL && r->next != NULL) {
 		/* merge */
@@ -1812,14 +1808,14 @@
 	return 0;
 }
 
-int avrule_read_operations(struct av_operations_range_list **rangehead)
+int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
 {
 	char *id;
-	struct av_operations_range_list *rnew, *r = NULL;
+	struct av_ioctl_range_list *rnew, *r = NULL;
 	*rangehead = NULL;
 	uint8_t omit = 0;
 
-	/* read in all the operations */
+	/* read in all the ioctl commands */
 	while ((id = queue_remove(id_queue))) {
 		if (strcmp(id,"~") == 0) {
 			/* these are values to be omitted */
@@ -1837,7 +1833,7 @@
 			free(id);
 		} else {
 			/* read in new low value */
-			rnew = malloc(sizeof(struct av_operations_range_list));
+			rnew = malloc(sizeof(struct av_ioctl_range_list));
 			if (rnew == NULL)
 				goto error;
 			rnew->next = NULL;
@@ -1862,11 +1858,11 @@
 }
 
 /* flip to included ranges */
-int avrule_omit_operations(struct av_operations_range_list **rangehead)
+int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead)
 {
-	struct av_operations_range_list *rnew, *r, *newhead, *r2;
+	struct av_ioctl_range_list *rnew, *r, *newhead, *r2;
 
-	rnew = calloc(1, sizeof(struct av_operations_range_list));
+	rnew = calloc(1, sizeof(struct av_ioctl_range_list));
 	if (!rnew)
 		goto error;
 
@@ -1884,7 +1880,7 @@
 
 	while (r) {
 		r2->range.high = r->range.low - 1;
-		rnew = calloc(1, sizeof(struct av_operations_range_list));
+		rnew = calloc(1, sizeof(struct av_ioctl_range_list));
 		if (!rnew)
 			goto error;
 		r2->next = rnew;
@@ -1910,27 +1906,27 @@
 	return -1;
 }
 
-int avrule_operation_ranges(struct av_operations_range_list **rangelist)
+int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist)
 {
-	struct av_operations_range_list *rangehead;
+	struct av_ioctl_range_list *rangehead;
 	uint8_t omit;
 
 	/* read in ranges to include and omit */
-	if (avrule_read_operations(&rangehead))
+	if (avrule_read_ioctls(&rangehead))
 		return -1;
 	omit = rangehead->omit;
 	if (rangehead == NULL) {
-		yyerror("error processing ioctl operations");
+		yyerror("error processing ioctl commands");
 		return -1;
 	}
-	/* sort and merge the input operations */
-	if (avrule_sort_operations(&rangehead))
+	/* sort and merge the input ioctls */
+	if (avrule_sort_ioctls(&rangehead))
 		return -1;
-	if (avrule_merge_operations(&rangehead))
+	if (avrule_merge_ioctls(&rangehead))
 		return -1;
 	/* flip ranges if these are ommited*/
 	if (omit) {
-		if (avrule_omit_operations(&rangehead))
+		if (avrule_omit_ioctls(&rangehead))
 			return -1;
 	}
 
@@ -1938,10 +1934,12 @@
 	return 0;
 }
 
-int define_te_avtab_operation_helper(int which, avrule_t ** rule)
+int define_te_avtab_xperms_helper(int which, avrule_t ** rule)
 {
 	char *id;
 	class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
+	class_datum_t *cladatum;
+	perm_datum_t *perdatum = NULL;
 	ebitmap_t tclasses;
 	ebitmap_node_t *node;
 	avrule_t *avrule;
@@ -1959,7 +1957,7 @@
 	avrule->line = policydb_lineno;
 	avrule->source_line = source_lineno;
 	avrule->source_filename = strdup(source_file);
-	avrule->ops = NULL;
+	avrule->xperms = NULL;
 	if (!avrule->source_filename) {
 		yyerror("out of memory");
 		return -1;
@@ -1968,7 +1966,7 @@
 	while ((id = queue_remove(id_queue))) {
 		if (set_types
 		    (&avrule->stypes, id, &add,
-		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
+		     which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
 			ret = -1;
 			goto out;
 		}
@@ -1982,7 +1980,7 @@
 		}
 		if (set_types
 		    (&avrule->ttypes, id, &add,
-		     which == AVRULE_NEVERALLOW ? 1 : 0)) {
+		     which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
 			ret = -1;
 			goto out;
 		}
@@ -1994,6 +1992,7 @@
 		goto out;
 
 	perms = NULL;
+	id = queue_head(id_queue);
 	ebitmap_for_each_bit(&tclasses, node, i) {
 		if (!ebitmap_node_get_bit(node, i))
 			continue;
@@ -2011,6 +2010,29 @@
 		if (tail)
 			tail->next = cur_perms;
 		tail = cur_perms;
+
+		cladatum = policydbp->class_val_to_struct[i];
+		perdatum = hashtab_search(cladatum->permissions.table, id);
+		if (!perdatum) {
+			if (cladatum->comdatum) {
+				perdatum = hashtab_search(cladatum->comdatum->
+							permissions.table,
+							id);
+			}
+		}
+		if (!perdatum) {
+			yyerror2("permission %s is not defined"
+				     " for class %s", id,
+				     policydbp->p_class_val_to_name[i]);
+			continue;
+		} else if (!is_perm_in_scope (id, policydbp->p_class_val_to_name[i])) {
+			yyerror2("permission %s of class %s is"
+			     " not within scope", id,
+			     policydbp->p_class_val_to_name[i]);
+			continue;
+		} else {
+			cur_perms->data |= 1U << (perdatum->s.value - 1);
+		}
 	}
 
 	ebitmap_destroy(&tclasses);
@@ -2023,95 +2045,102 @@
 }
 
 /* index of the u32 containing the permission */
-#define OP_IDX(x) (x >> 5)
+#define XPERM_IDX(x) (x >> 5)
 /* set bits 0 through x-1 within the u32 */
-#define OP_SETBITS(x) ((1 << (x & 0x1f)) - 1)
+#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
 /* low value for this u32 */
-#define OP_LOW(x) (x << 5)
+#define XPERM_LOW(x) (x << 5)
 /* high value for this u32 */
-#define OP_HIGH(x) (((x + 1) << 5) - 1)
-void avrule_operation_setrangebits(uint16_t low, uint16_t high, av_operations_t *ops)
+#define XPERM_HIGH(x) (((x + 1) << 5) - 1)
+void avrule_xperm_setrangebits(uint16_t low, uint16_t high,
+				av_extended_perms_t *xperms)
 {
 	unsigned int i;
 	uint16_t h = high + 1;
-	/* for each u32 that this low-high range touches, set type permissions */
-	for (i = OP_IDX(low); i <= OP_IDX(high); i++) {
+	/* for each u32 that this low-high range touches, set driver permissions */
+	for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
 		/* set all bits in u32 */
-		if ((low <= OP_LOW(i)) && (high >= OP_HIGH(i)))
-			ops->perms[i] |= ~0U;
+		if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+			xperms->perms[i] |= ~0U;
 		/* set low bits */
-		else if ((low <= OP_LOW(i)) && (high < OP_HIGH(i)))
-			ops->perms[i] |= OP_SETBITS(h);
+		else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
+			xperms->perms[i] |= XPERM_SETBITS(h);
 		/* set high bits */
-		else if ((low > OP_LOW(i)) && (high >= OP_HIGH(i)))
-			ops->perms[i] |= ~0U - OP_SETBITS(low);
+		else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+			xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
 		/* set middle bits */
-		else if ((low > OP_LOW(i)) && (high <= OP_HIGH(i)))
-			ops->perms[i] |= OP_SETBITS(h) - OP_SETBITS(low);
+		else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
+			xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
 	}
 }
 
-int avrule_operation_used(av_operations_t *ops)
+int avrule_xperms_used(av_extended_perms_t *xperms)
 {
 	unsigned int i;
 
-	for (i = 0; i < sizeof(ops->perms)/sizeof(ops->perms[0]); i++) {
-		if (ops->perms[i])
+	for (i = 0; i < sizeof(xperms->perms)/sizeof(xperms->perms[0]); i++) {
+		if (xperms->perms[i])
 			return 1;
 	}
 	return 0;
 }
 
-#define OP_TYPE(x) (x >> 8)
-#define OP_NUM(x) (x & 0xff)
-#define OP_CMD(type, num) ((type << 8) + num)
-int avrule_operation_partialtype(struct av_operations_range_list *rangelist,
-				av_operations_t *complete_type,
-				av_operations_t **operations)
+/*
+ * using definitions found in kernel document ioctl-number.txt
+ * The kernel components of an ioctl command are:
+ * dir, size, driver, and fucntion. Only the driver and function fields
+ * are considered here
+ */
+#define IOC_DRIV(x) (x >> 8)
+#define IOC_FUNC(x) (x & 0xff)
+#define IOC_CMD(driver, func) ((driver << 8) + func)
+int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist,
+				av_extended_perms_t *complete_driver,
+				av_extended_perms_t **extended_perms)
 {
-	struct av_operations_range_list *r;
-	av_operations_t *ops;
+	struct av_ioctl_range_list *r;
+	av_extended_perms_t *xperms;
 	uint8_t low, high;
 
-	ops = calloc(1, sizeof(av_operations_t));
-	if (!ops) {
+	xperms = calloc(1, sizeof(av_extended_perms_t));
+	if (!xperms) {
 		yyerror("out of memory");
 		return - 1;
 	}
 
 	r = rangelist;
 	while(r) {
-		low = OP_TYPE(r->range.low);
-		high = OP_TYPE(r->range.high);
-		if (complete_type) {
-			if (!operation_perm_test(low, complete_type->perms))
-				operation_perm_set(low, ops->perms);
-			if (!operation_perm_test(high, complete_type->perms))
-				operation_perm_set(high, ops->perms);
+		low = IOC_DRIV(r->range.low);
+		high = IOC_DRIV(r->range.high);
+		if (complete_driver) {
+			if (!xperm_test(low, complete_driver->perms))
+				xperm_set(low, xperms->perms);
+			if (!xperm_test(high, complete_driver->perms))
+				xperm_set(high, xperms->perms);
 		} else {
-			operation_perm_set(low, ops->perms);
-			operation_perm_set(high, ops->perms);
+			xperm_set(low, xperms->perms);
+			xperm_set(high, xperms->perms);
 		}
 		r = r->next;
 	}
-	if (avrule_operation_used(ops)) {
-		*operations = ops;
+	if (avrule_xperms_used(xperms)) {
+		*extended_perms = xperms;
 	} else {
-		free(ops);
-		*operations = NULL;
+		free(xperms);
+		*extended_perms = NULL;
 	}
 	return 0;
 
 }
 
-int avrule_operation_completetype(struct av_operations_range_list *rangelist,
-			av_operations_t **operations)
+int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist,
+			av_extended_perms_t **extended_perms)
 {
-	struct av_operations_range_list *r;
-	av_operations_t *ops;
+	struct av_ioctl_range_list *r;
+	av_extended_perms_t *xperms;
 	uint16_t low, high;
-	ops = calloc(1, sizeof(av_operations_t));
-	if (!ops) {
+	xperms = calloc(1, sizeof(av_extended_perms_t));
+	if (!xperms) {
 		yyerror("out of memory");
 		return - 1;
 	}
@@ -2119,83 +2148,86 @@
 	r = rangelist;
 	while(r) {
 		/*
-		 * Any type that has numbers 0x00 - 0xff is a complete type,
+		 * Any driver code that has sequence 0x00 - 0xff is a complete code,
 		 *
-		 * if command number = 0xff, then round high up to next type,
-		 * else 0x00 - 0xfe keep current type
+		 * if command number = 0xff, then round high up to next code,
+		 * else 0x00 - 0xfe keep current code
 		 * of this range. temporarily u32 for the + 1
 		 * to account for possible rollover before right shift
 		 */
-		high = OP_TYPE((uint32_t) (r->range.high + 1));
-		/* if 0x00 keep current type else 0x01 - 0xff round up to next type */
-		low = OP_TYPE(r->range.low);
-		if (OP_NUM(r->range.low))
+		high = IOC_DRIV((uint32_t) (r->range.high + 1));
+		/* if 0x00 keep current driver code else 0x01 - 0xff round up to next code*/
+		low = IOC_DRIV(r->range.low);
+		if (IOC_FUNC(r->range.low))
 			low++;
 		if (high > low)
-			avrule_operation_setrangebits(low, high - 1, ops);
+			avrule_xperm_setrangebits(low, high - 1, xperms);
 		r = r->next;
 	}
-	if (avrule_operation_used(ops)) {
-		*operations = ops;
+	if (avrule_xperms_used(xperms)) {
+		xperms->driver = 0x00;
+		xperms->specified = AVRULE_XPERMS_IOCTLDRIVER;
+		*extended_perms = xperms;
 	} else {
-		free(ops);
-		*operations = NULL;
+		free(xperms);
+		*extended_perms = NULL;
 	}
 	return 0;
 }
 
-int avrule_operation_num(struct av_operations_range_list *rangelist,
-		av_operations_t **operations, unsigned int type)
+int avrule_ioctl_func(struct av_ioctl_range_list *rangelist,
+		av_extended_perms_t **extended_perms, unsigned int driver)
 {
-	struct av_operations_range_list *r;
-	av_operations_t *ops;
+	struct av_ioctl_range_list *r;
+	av_extended_perms_t *xperms;
 	uint16_t low, high;
 
-	*operations = NULL;
-	ops = calloc(1, sizeof(av_operations_t));
-	if (!ops) {
+	*extended_perms = NULL;
+	xperms = calloc(1, sizeof(av_extended_perms_t));
+	if (!xperms) {
 		yyerror("out of memory");
 		return - 1;
 	}
 
 	r = rangelist;
-	/* for the passed in types, find the ranges that apply */
+	/* for the passed in driver code, find the ranges that apply */
 	while (r) {
 		low = r->range.low;
 		high = r->range.high;
-		if ((type != OP_TYPE(low)) && (type != OP_TYPE(high))) {
+		if ((driver != IOC_DRIV(low)) && (driver != IOC_DRIV(high))) {
 			r = r->next;
 			continue;
 		}
 
-		if (type == OP_TYPE(low)) {
-			if (high > OP_CMD(type, 0xff))
-				high = OP_CMD(type, 0xff);
+		if (driver == IOC_DRIV(low)) {
+			if (high > IOC_CMD(driver, 0xff))
+				high = IOC_CMD(driver, 0xff);
 
 		} else {
-			if (low < OP_CMD(type, 0))
-				low = OP_CMD(type, 0);
+			if (low < IOC_CMD(driver, 0))
+				low = IOC_CMD(driver, 0);
 		}
 
-		low = OP_NUM(low);
-		high = OP_NUM(high);
-		avrule_operation_setrangebits(low, high, ops);
-		ops->type = type;
+		low = IOC_FUNC(low);
+		high = IOC_FUNC(high);
+		avrule_xperm_setrangebits(low, high, xperms);
+		xperms->driver = driver;
+		xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION;
 		r = r->next;
 	}
 
-	if (avrule_operation_used(ops)) {
-		*operations = ops;
+	if (avrule_xperms_used(xperms)) {
+		*extended_perms = xperms;
 	} else {
-		free(ops);
-		*operations = NULL;
+		free(xperms);
+		*extended_perms = NULL;
 	}
 	return 0;
 }
 
-void avrule_operation_freeranges(struct av_operations_range_list *rangelist)
+void avrule_ioctl_freeranges(struct av_ioctl_range_list *rangelist)
 {
-	struct av_operations_range_list *r, *tmp;
+	struct av_ioctl_range_list *r, *tmp;
 	r = rangelist;
 	while (r) {
 		tmp = r;
@@ -2204,12 +2236,12 @@
 	}
 }
 
-unsigned int operation_for_each_bit(unsigned int *bit, av_operations_t *ops)
+unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms)
 {
 	unsigned int i;
-	for (i = *bit; i < sizeof(ops->perms)*8; i++) {
-		if (operation_perm_test(i,ops->perms)) {
-			operation_perm_clear(i, ops->perms);
+	for (i = *bit; i < sizeof(xperms->perms)*8; i++) {
+		if (xperm_test(i,xperms->perms)) {
+			xperm_clear(i, xperms->perms);
 			*bit = i;
 			return 1;
 		}
@@ -2236,6 +2268,10 @@
 	}
 	dest->line = src->line;
 	dest->source_filename = strdup(source_file);
+	if (!dest->source_filename) {
+		yyerror("out of memory");
+		return -1;
+	}
 	dest->source_line = src->source_line;
 
 	/* increment through the class perms and copy over */
@@ -2261,14 +2297,75 @@
 	return 0;
 }
 
-int define_te_avtab_operation(int which)
+int define_te_avtab_ioctl(avrule_t *avrule_template)
+{
+	avrule_t *avrule;
+	struct av_ioctl_range_list *rangelist;
+	av_extended_perms_t *complete_driver, *partial_driver, *xperms;
+	unsigned int i;
+
+
+	/* organize ioctl ranges */
+	if (avrule_ioctl_ranges(&rangelist))
+		return -1;
+
+	/* create rule for ioctl driver types that are entirely enabled */
+	if (avrule_ioctl_completedriver(rangelist, &complete_driver))
+		return -1;
+	if (complete_driver) {
+		avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
+		if (!avrule) {
+			yyerror("out of memory");
+			return -1;
+		}
+		if (avrule_cpy(avrule, avrule_template))
+			return -1;
+		avrule->xperms = complete_driver;
+		append_avrule(avrule);
+	}
+
+	/* flag ioctl driver codes that are partially enabled */
+	if (avrule_ioctl_partialdriver(rangelist, complete_driver, &partial_driver))
+		return -1;
+
+	if (!partial_driver || !avrule_xperms_used(partial_driver))
+		goto done;
+
+	/*
+	 * create rule for each partially used driver codes
+	 * "partially used" meaning that the code number e.g. socket 0x89
+	 * has some permission bits set and others not set.
+	 */
+	i = 0;
+	while (xperms_for_each_bit(&i, partial_driver)) {
+		if (avrule_ioctl_func(rangelist, &xperms, i))
+			return -1;
+
+		if (xperms) {
+			avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
+			if (!avrule) {
+				yyerror("out of memory");
+				return -1;
+			}
+			if (avrule_cpy(avrule, avrule_template))
+				return -1;
+			avrule->xperms = xperms;
+			append_avrule(avrule);
+		}
+	}
+
+done:
+	if (partial_driver)
+		free(partial_driver);
+
+	return 0;
+}
+
+int define_te_avtab_extended_perms(int which)
 {
 	char *id;
-	avrule_t *avrule_template;
-	avrule_t *avrule;
-	struct av_operations_range_list *rangelist;
-	av_operations_t *complete_type, *partial_type, *ops;
 	unsigned int i;
+	avrule_t *avrule_template;
 
 	if (pass == 1) {
 		for (i = 0; i < 4; i++) {
@@ -2279,65 +2376,18 @@
 	}
 
 	/* populate avrule template with source/target/tclass */
-	if (define_te_avtab_operation_helper(which, &avrule_template))
+	if (define_te_avtab_xperms_helper(which, &avrule_template))
 		return -1;
 
-	/* organize operation ranges */
-	if (avrule_operation_ranges(&rangelist))
-		return -1;
-
-	/* create rule for ioctl operation types that are entirely enabled */
-	if (avrule_operation_completetype(rangelist, &complete_type))
-		return -1;
-	if (complete_type) {
-		avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
-		if (!avrule) {
-			yyerror("out of memory");
+	id = queue_remove(id_queue);
+	if (strcmp(id,"ioctl") == 0) {
+		if (define_te_avtab_ioctl(avrule_template))
 			return -1;
-		}
-		if (avrule_cpy(avrule, avrule_template))
-			return -1;
-		avrule->ops = complete_type;
-		if (which == AVRULE_OPNUM_ALLOWED)
-			avrule->specified = AVRULE_OPTYPE_ALLOWED;
-		else if (which == AVRULE_OPNUM_AUDITALLOW)
-			avrule->specified = AVRULE_OPTYPE_AUDITALLOW;
-		else if (which == AVRULE_OPNUM_DONTAUDIT)
-			avrule->specified = AVRULE_OPTYPE_DONTAUDIT;
-
-		append_avrule(avrule);
+		free(id);
+	} else {
+		yyerror("only ioctl extended permissions are supported");
+		return -1;
 	}
-
-	/* flag ioctl types that are partially enabled */
-	if (avrule_operation_partialtype(rangelist, complete_type, &partial_type))
-		return -1;
-
-	if (!partial_type || !avrule_operation_used(partial_type))
-		goto done;
-
-	/* create rule for each partially enabled type */
-	i = 0;
-	while (operation_for_each_bit(&i, partial_type)) {
-		if (avrule_operation_num(rangelist, &ops, i))
-			return -1;
-
-		if (ops) {
-			avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
-			if (!avrule) {
-				yyerror("out of memory");
-				return -1;
-			}
-			if (avrule_cpy(avrule, avrule_template))
-				return -1;
-			avrule->ops = ops;
-			append_avrule(avrule);
-		}
-	}
-
-done:
-	if (partial_type)
-		free(partial_type);
-
 	return 0;
 }
 
@@ -2365,7 +2415,7 @@
 	avrule->line = policydb_lineno;
 	avrule->source_line = source_lineno;
 	avrule->source_filename = strdup(source_file);
-	avrule->ops = NULL;
+	avrule->xperms = NULL;
 	if (!avrule->source_filename) {
 		yyerror("out of memory");
 		return -1;
@@ -2745,7 +2795,7 @@
 	role_datum_t *rdp = (role_datum_t *) arg;
 	role_datum_t *rdatum = (role_datum_t *) datum;
 	ebitmap_node_t *node;
-	int i;
+	uint32_t i;
 
 	/* Don't bother to process against self role */
 	if (rdatum->s.value == rdp->s.value)
@@ -3291,8 +3341,14 @@
 		append_filename_trans(ftr);
 
 		ftr->name = strdup(name);
-		ftr->stypes = stypes;
-		ftr->ttypes = ttypes;
+		if (type_set_cpy(&ftr->stypes, &stypes)) {
+			yyerror("out of memory");
+			goto bad;
+		}
+		if (type_set_cpy(&ftr->ttypes, &ttypes)) {
+			yyerror("out of memory");
+			goto bad;
+		}
 		ftr->tclass = c + 1;
 		ftr->otype = otype;
 	}
diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h
index 43c7c08..964baae 100644
--- a/checkpolicy/policy_define.h
+++ b/checkpolicy/policy_define.h
@@ -58,7 +58,7 @@
 int define_filename_trans(void);
 int define_sens(void);
 int define_te_avtab(int which);
-int define_te_avtab_operation(int which);
+int define_te_avtab_extended_perms(int which);
 int define_typealias(void);
 int define_typeattribute(void);
 int define_typebounds(void);
diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y
index 059b7b8..3b6a2f8 100644
--- a/checkpolicy/policy_parse.y
+++ b/checkpolicy/policy_parse.y
@@ -126,6 +126,10 @@
 %token AUDITALLOW
 %token AUDITDENY
 %token DONTAUDIT
+%token ALLOWXPERM
+%token AUDITALLOWXPERM
+%token DONTAUDITXPERM
+%token NEVERALLOWXPERM
 %token SOURCE
 %token TARGET
 %token SAMEUSER
@@ -457,9 +461,10 @@
 			| auditdeny_def
 			| dontaudit_def
 			| neverallow_def
-			| operation_allow_def
-			| operation_auditallow_def
-			| operation_dontaudit_def
+			| xperm_allow_def
+			| xperm_auditallow_def
+			| xperm_dontaudit_def
+			| xperm_neverallow_def
 			;
 allow_def		: ALLOW names names ':' names names  ';'
 			{if (define_te_avtab(AVRULE_ALLOWED)) return -1; }
@@ -476,14 +481,17 @@
 neverallow_def		: NEVERALLOW names names ':' names names  ';'
 			{if (define_te_avtab(AVRULE_NEVERALLOW)) return -1; }
 		        ;
-operation_allow_def	: ALLOW names names ':' names  operations ';'
-			{if (define_te_avtab_operation(AVRULE_OPNUM_ALLOWED)) return -1; }
+xperm_allow_def		: ALLOWXPERM names names ':' names identifier xperms ';'
+			{if (define_te_avtab_extended_perms(AVRULE_XPERMS_ALLOWED)) return -1; }
 		        ;
-operation_auditallow_def: AUDITALLOW names names ':' names operations ';'
-			{if (define_te_avtab_operation(AVRULE_OPNUM_AUDITALLOW)) return -1; }
+xperm_auditallow_def	: AUDITALLOWXPERM names names ':' names identifier xperms ';'
+			{if (define_te_avtab_extended_perms(AVRULE_XPERMS_AUDITALLOW)) return -1; }
 		        ;
-operation_dontaudit_def	: DONTAUDIT names names ':' names operations ';'
-			{if (define_te_avtab_operation(AVRULE_OPNUM_DONTAUDIT)) return -1; }
+xperm_dontaudit_def	: DONTAUDITXPERM names names ':' names identifier xperms ';'
+			{if (define_te_avtab_extended_perms(AVRULE_XPERMS_DONTAUDIT)) return -1; }
+		        ;
+xperm_neverallow_def	: NEVERALLOWXPERM names names ':' names identifier xperms ';'
+			{if (define_te_avtab_extended_perms(AVRULE_XPERMS_NEVERALLOW)) return -1; }
 		        ;
 attribute_role_def	: ATTRIBUTE_ROLE identifier ';'
 			{if (define_attrib_role()) return -1; }
@@ -749,26 +757,26 @@
 ipv4_addr_def		: IPV4_ADDR
 			{ if (insert_id(yytext,0)) return -1; }
 			;
-operations		: operation
+xperms		: xperm
 			{ if (insert_separator(0)) return -1; }
-			| nested_operation_set
+			| nested_xperm_set
 			{ if (insert_separator(0)) return -1; }
-			| tilde operation
+			| tilde xperm
                         { if (insert_id("~", 0)) return -1; }
-			| tilde nested_operation_set
+			| tilde nested_xperm_set
 			{ if (insert_id("~", 0)) return -1;
 			  if (insert_separator(0)) return -1; }
 			;
-nested_operation_set	: '{' nested_operation_list '}'
+nested_xperm_set	: '{' nested_xperm_list '}'
 			;
-nested_operation_list	: nested_operation_element
-			| nested_operation_list nested_operation_element
+nested_xperm_list	: nested_xperm_element
+			| nested_xperm_list nested_xperm_element
 			;
-nested_operation_element: operation '-' { if (insert_id("-", 0)) return -1; } operation
-			| operation
-			| nested_operation_set
+nested_xperm_element: xperm '-' { if (insert_id("-", 0)) return -1; } xperm
+			| xperm
+			| nested_xperm_set
 			;
-operation		: number
+xperm		: number
                         { if (insert_id(yytext,0)) return -1; }
 			;
 security_context_def	: identifier ':' identifier ':' identifier opt_mls_range_def
diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l
index 108edbc..22da338 100644
--- a/checkpolicy/policy_scan.l
+++ b/checkpolicy/policy_scan.l
@@ -142,6 +142,14 @@
 auditdeny		        { return(AUDITDENY); }
 DONTAUDIT |
 dontaudit                       { return(DONTAUDIT); }
+ALLOWXPERM |
+allowxperm			{ return(ALLOWXPERM); }
+AUDITALLOWXPERM |
+auditallowxperm			{ return(AUDITALLOWXPERM); }
+DONTAUDITXPERM |
+dontauditxperm			{ return(DONTAUDITXPERM); }
+NEVERALLOWXPERM |
+neverallowxperm			{ return(NEVERALLOWXPERM); }
 SOURCE |
 source			        { return(SOURCE); }
 TARGET |
diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c
index 157361a..86f5688 100644
--- a/checkpolicy/test/dispol.c
+++ b/checkpolicy/test/dispol.c
@@ -54,56 +54,6 @@
 	return 0;
 }
 
-#define operation_perm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
-#define next_bit_in_range(i, p) \
-	((i + 1 < sizeof(p)*8) && operation_perm_test((i + 1), p))
-
-int render_operations(avtab_operations_t *ops, avtab_key_t * key, FILE * fp)
-{
-	uint16_t value;
-	uint16_t low_bit;
-	uint16_t low_value;
-	unsigned int bit;
-	unsigned int in_range = 0;
-
-	fprintf(fp, "{ ");
-	for (bit = 0; bit < sizeof(ops->perms)*8; bit++) {
-		if (!operation_perm_test(bit, ops->perms))
-			continue;
-
-		if (in_range && next_bit_in_range(bit, ops->perms)) {
-			/* continue until high value found */
-			continue;
-		} else if (next_bit_in_range(bit, ops->perms)) {
-			/* low value */
-			low_bit = bit;
-			in_range = 1;
-			continue;
-		}
-
-		if (key->specified & AVTAB_OPNUM) {
-			value = ops->type<<8 | bit;
-			low_value = ops->type<<8 | low_bit;
-			if (in_range)
-				fprintf(fp, "0x%hx-0x%hx ", low_value, value);
-			else
-				fprintf(fp, "0x%hx ", value);
-		} else if (key->specified & AVTAB_OPTYPE) {
-			value = bit << 8;
-			low_value = low_bit << 8;
-			if (in_range)
-				fprintf(fp, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff));
-			else
-				fprintf(fp, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff));
-
-		}
-		if (in_range)
-			in_range = 0;
-	}
-	fprintf(fp, "}");
-	return 0;
-}
-
 int render_type(uint32_t type, policydb_t * p, FILE * fp)
 {
 	fprintf(fp, "%s", p->p_type_val_to_name[type - 1]);
@@ -197,16 +147,15 @@
 			render_type(datum->data, p, fp);
 			fprintf(fp, ";\n");
 		}
-	} else if (key->specified & AVTAB_OP) {
-		if (key->specified & (AVTAB_OPNUM_ALLOWED|AVTAB_OPTYPE_ALLOWED))
-			fprintf(fp, "allow ");
-		else if (key->specified & (AVTAB_OPNUM_AUDITALLOW|AVTAB_OPTYPE_AUDITALLOW))
-			fprintf(fp, "auditallow ");
-		else if (key->specified & (AVTAB_OPNUM_DONTAUDIT|AVTAB_OPTYPE_DONTAUDIT))
-			fprintf(fp, "dontaudit ");
+	} else if (key->specified & AVTAB_XPERMS) {
+		if (key->specified & AVTAB_XPERMS_ALLOWED)
+			fprintf(fp, "allowxperm ");
+		else if (key->specified & AVTAB_XPERMS_AUDITALLOW)
+			fprintf(fp, "auditallowxperm ");
+		else if (key->specified & AVTAB_XPERMS_DONTAUDIT)
+			fprintf(fp, "dontauditxperm ");
 		render_key(key, p, fp);
-		render_operations(datum->ops, key, fp);
-		fprintf(fp, ";\n");
+		fprintf(fp, "%s;\n", sepol_extended_perms_to_string(datum->xperms));
 	} else {
 		fprintf(fp, "     ERROR: no valid rule type specified\n");
 		return -1;
diff --git a/libselinux/ChangeLog b/libselinux/ChangeLog
index 6a010b7..3501428 100644
--- a/libselinux/ChangeLog
+++ b/libselinux/ChangeLog
@@ -1,3 +1,30 @@
+	* label_file: fix memory leaks and uninitialized jump, from William Roberts.
+	* Replace selabel_digest hash function, from Richard Haines.
+	* Fix selabel_open(3) services if no digest requested, from Richard Haines.
+	* Add selabel_digest function, from Richard Haines.
+	* Fix parallel build with swig python, from Jason Zaman.
+	* Flush the class/perm string mapping cache on policy reload, from Stephen Smalley.
+	* Fix restorecon when path has no context, from Nir Soffer.
+	* Free memory when processing media and x specfiles, from Richard Haines.
+	* Fix mmap memory release for file labeling, from Richard Haines.
+	* Add explicit dependency for pywrap on selinux.py, from Wenzong Fan.
+	* Add policy context validation to sefcontext_compile, from Richard Haines.
+	* Do not treat an empty file_contexts(.local) as an error, from Stephen Smalley.
+	* Fail hard on invalid property_contexts entries, from Stephen Smalley.
+	* Fail hard on invalid file_contexts entries, from Stephen Smalley.
+	* Support context validation on file_contexts.bin, from Stephen Smalley.
+	* Test for file_contexts.bin format by magic number, from Stephen Smalley.
+	* Add selabel_cmp interface and label_file backend, from Stephen Smalley.
+	* Support specifying file_contexts.bin file path, from Stephen Smalley.
+	* Support file_contexts.bin without file_contexts, from Stephen Smalley.
+	* Simplify procattr cache, from Stephen Smalley.
+	* Use /proc/thread-self when available, from Stephen Smalley.
+	* Add const to selinux_opt for label backends, from Richard Haines.
+	* Fix binary file labels for regexes with metachars, from Richard Haines.
+	* Fix file labels for regexes with metachars, from Jeff Vander Stoep.
+	* Fix if file_contexts not '\n' terminated, from Richard Haines.
+	* Enhance file context support, from Richard Haines.
+	* Fix property processing and cleanup formatting, from Richard Haines.
 	* Add read_spec_entries function to replace sscanf, from Richard Haines.
 	* Support consistent mode size for bin files, from Richard Haines.
 	* Expunge remaining references to flask.h and av_permissions.h, from Stephen Smalley.
diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h
index 7a94a92..f0b1e10 100644
--- a/libselinux/include/selinux/label.h
+++ b/libselinux/include/selinux/label.h
@@ -49,8 +49,10 @@
 #define SELABEL_OPT_PATH	3
 /* select a subset of the search space as an optimization (file backend) */
 #define SELABEL_OPT_SUBSET	4
+/* require a hash calculation on spec files */
+#define SELABEL_OPT_DIGEST	5
 /* total number of options */
-#define SELABEL_NOPT		5
+#define SELABEL_NOPT		6
 
 /*
  * Label operations
@@ -69,7 +71,8 @@
  * @errno set on failure.
  */
 struct selabel_handle *selabel_open(unsigned int backend,
-				    struct selinux_opt *opts, unsigned nopts);
+				    const struct selinux_opt *opts,
+				    unsigned nopts);
 
 /**
  * selabel_close - Close a labeling handle.
@@ -106,6 +109,43 @@
 			      const char *key, const char **aliases, int type);
 
 /**
+ * selabel_digest - Retrieve the SHA1 digest and the list of specfiles used to
+ *		    generate the digest. The SELABEL_OPT_DIGEST option must
+ *		    be set in selabel_open() to initiate the digest generation.
+ * @handle: specifies backend instance to query
+ * @digest: returns a pointer to the SHA1 digest.
+ * @digest_len: returns length of digest in bytes.
+ * @specfiles: a list of specfiles used in the SHA1 digest generation.
+ *	       The list is NULL terminated and will hold @num_specfiles entries.
+ * @num_specfiles: number of specfiles in the list.
+ *
+ * Return %0 on success, -%1 with @errno set on failure.
+ */
+int selabel_digest(struct selabel_handle *rec,
+			    unsigned char **digest, size_t *digest_len,
+			    char ***specfiles, size_t *num_specfiles);
+
+enum selabel_cmp_result {
+	SELABEL_SUBSET,
+	SELABEL_EQUAL,
+	SELABEL_SUPERSET,
+	SELABEL_INCOMPARABLE
+};
+
+/**
+ * selabel_cmp - Compare two label configurations.
+ * @h1: handle for the first label configuration
+ * @h2: handle for the first label configuration
+ *
+ * Compare two label configurations.
+ * Return %SELABEL_SUBSET if @h1 is a subset of @h2, %SELABEL_EQUAL
+ * if @h1 is identical to @h2, %SELABEL_SUPERSET if @h1 is a superset
+ * of @h2, and %SELABEL_INCOMPARABLE if @h1 and @h2 are incomparable.
+ */
+enum selabel_cmp_result selabel_cmp(struct selabel_handle *h1,
+				    struct selabel_handle *h2);
+
+/**
  * selabel_stats - log labeling operation statistics.
  * @handle: specifies backend instance to query
  *
diff --git a/libselinux/man/man3/selabel_digest.3 b/libselinux/man/man3/selabel_digest.3
new file mode 100644
index 0000000..56a008f
--- /dev/null
+++ b/libselinux/man/man3/selabel_digest.3
@@ -0,0 +1,61 @@
+.TH "selabel_digest" "3" "16 Sept 2015" "" "SELinux API documentation"
+.SH "NAME"
+selabel_digest \- Return digest of specfiles and list of files used
+.
+.SH "SYNOPSIS"
+.B #include <selinux/selinux.h>
+.br
+.B #include <selinux/label.h>
+.sp
+.BI "int selabel_digest(struct selabel_handle *" hnd ,
+.in +\w'int selabel_digest('u
+.BI "unsigned char **" digest ,
+.BI "size_t *" digest_len ,
+.br
+.BI "char ***" specfiles,
+.BI "size_t *" num_specfiles ");"
+.in
+.
+.SH "DESCRIPTION"
+.BR selabel_digest ()
+performs an operation on the handle
+.IR hnd ,
+returning the results of the SHA1 digest pointed to by
+.IR digest ,
+whose length will be
+.IR digest_len .
+The list of specfiles used in the SHA1 digest calculation is returned in
+.I specfiles
+with the number of entries in
+.IR num_specfiles .
+.sp
+To enable
+.BR selabel_digest ()
+to return this information the
+.B SELABEL_OPT_DIGEST
+option must be enable in
+.BR selabel_open (3).
+.sp
+The result of
+.BR selabel_digest ()
+must not be used after
+.BR selabel_close (3).
+.
+.SH "RETURN VALUE"
+On success, zero is returned.  On error, \-1 is returned and
+.I errno
+is set appropriately.
+.
+.SH "ERRORS"
+.TP
+.B EINVAL
+No digest available (returned if
+.B SELABEL_OPT_DIGEST
+option not enabled).
+.TP
+.B ENOMEM
+An attempt to allocate memory failed.
+.
+.SH "SEE ALSO"
+.BR selabel_open (3),
+.BR selinux (8)
diff --git a/libselinux/man/man3/selabel_open.3 b/libselinux/man/man3/selabel_open.3
index 00f2828..971ebc1 100644
--- a/libselinux/man/man3/selabel_open.3
+++ b/libselinux/man/man3/selabel_open.3
@@ -12,7 +12,7 @@
 .sp
 .BI "struct selabel_handle *selabel_open(int " backend , 
 .in +\w'struct selabel_handle *selabel_open('u
-.BI "struct selinux_opt *" options ,
+.BI "const struct selinux_opt *" options ,
 .br
 .BI "unsigned " nopt ");"
 .in
@@ -67,6 +67,11 @@
 is used; a custom validation function can be provided via
 .BR selinux_set_callback (3).
 Note that an invalid context may not be treated as an error unless it is actually encountered during a lookup operation.
+.TP
+.B SELABEL_OPT_DIGEST
+A non-null value for this option enables the generation of an SHA1 digest of
+the spec files loaded as described in
+.BR selabel_digest (3)
 .
 .SH "BACKENDS"
 .TP
diff --git a/libselinux/man/man8/sefcontext_compile.8 b/libselinux/man/man8/sefcontext_compile.8
index 810d22a..b77ff3a 100644
--- a/libselinux/man/man8/sefcontext_compile.8
+++ b/libselinux/man/man8/sefcontext_compile.8
@@ -1,15 +1,67 @@
-.TH "sefcontext_compile" "8" "27 Jun 2013" "dwalsh@redhat.com" "SELinux Command Line documentation"
+.TH "sefcontext_compile" "8" "12 Aug 2015" "dwalsh@redhat.com" "SELinux Command Line documentation"
 .SH "NAME"
 sefcontext_compile \- compile file context regular expression files
 .
 .SH "SYNOPSIS"
-.B sefcontext_compile inputfile
+.B sefcontext_compile
+.RB [ \-o
+.IR outputfile ]
+.RB [ \-p
+.IR policyfile ]
+.I inputfile
 .
 .SH "DESCRIPTION"
-sefcontext_compile is used libsemanage to compile file context regular expressions into prce format.  sefcontext_compile writes the compiled prce file with the .bin suffix appended "inputfile".bin.  This compiled file is used by libselinux file labeling functions.
+.B sefcontext_compile
+is used to compile file context regular expressions into
+.BR prce (3)
+format.
+.sp
+The compiled file is used by libselinux file labeling functions.
+.sp
+By default
+.B sefcontext_compile
+writes the compiled prce file with the
+.B .bin
+suffix appended (e.g. \fIinputfile\fB.bin\fR).
+.SH OPTIONS
+.TP
+.B \-o
+Specify an
+.I outputfile
+that must be a fully qualified file name as the
+.B .bin
+suffix is not automatically added.
+.TP
+.B \-p
+Specify a binary
+.I policyfile
+that will be used to validate the context entries in the
+.I inputfile
+.br
+If an invalid context is found the pcre formatted file will not be written and
+an error will be returned.
 
-.SH "EXAMPLE"
+.SH "RETURN VALUE"
+On error -1 is returned.  On success 0 is returned.
+
+.SH "EXAMPLES"
+.B Example 1:
+.br
 sefcontext_compile /etc/selinux/targeted/contexts/files/file_contexts
+.sp
+Results in the following file being generated:
+.RS
+/etc/selinux/targeted/contexts/files/file_contexts.bin
+.RE
+.sp
+.B Example 2:
+.br
+sefcontext_compile -o new_fc.bin /etc/selinux/targeted/contexts/files/file_contexts
+.sp
+Results in the following file being generated in the cwd:
+.RS
+new_fc.bin
+.RE
 .
 .SH AUTHOR
 Dan Walsh, <dwalsh@redhat.com>
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
index ac25c1f..feab561 100644
--- a/libselinux/src/Makefile
+++ b/libselinux/src/Makefile
@@ -29,11 +29,12 @@
 SWIGIF= selinuxswig_python.i selinuxswig_python_exception.i
 SWIGRUBYIF= selinuxswig_ruby.i
 SWIGCOUT= selinuxswig_wrap.c
+SWIGPYOUT= selinux.py
 SWIGRUBYCOUT= selinuxswig_ruby_wrap.c
 SWIGLOBJ:= $(patsubst %.c,$(PYPREFIX)%.lo,$(SWIGCOUT))
 SWIGRUBYLOBJ:= $(patsubst %.c,%.lo,$(SWIGRUBYCOUT)) 
 SWIGSO=$(PYPREFIX)_selinux.so
-SWIGFILES=$(SWIGSO) selinux.py
+SWIGFILES=$(SWIGSO) $(SWIGPYOUT)
 SWIGRUBYSO=$(RUBYPREFIX)_selinux.so
 LIBSO=$(TARGET).$(LIBVERSION)
 AUDIT2WHYLOBJ=$(PYPREFIX)audit2why.lo
@@ -90,7 +91,7 @@
 
 all: $(LIBA) $(LIBSO) $(LIBPC)
 
-pywrap: all $(SWIGSO) $(AUDIT2WHYSO)
+pywrap: all $(SWIGFILES) $(AUDIT2WHYSO)
 
 rubywrap: all $(SWIGRUBYSO)
 
@@ -135,6 +136,8 @@
 $(SWIGCOUT): $(SWIGIF)
 	$(SWIG) $<
 
+$(SWIGPYOUT): $(SWIGCOUT)
+
 $(SWIGRUBYCOUT): $(SWIGRUBYIF)
 	$(SWIGRUBY) $<
 
@@ -154,7 +157,7 @@
 	test -d $(PYLIBDIR)/site-packages/selinux || install -m 755 -d $(PYLIBDIR)/site-packages/selinux
 	install -m 755 $(SWIGSO) $(PYLIBDIR)/site-packages/selinux/_selinux.so
 	install -m 755 $(AUDIT2WHYSO) $(PYLIBDIR)/site-packages/selinux/audit2why.so
-	install -m 644  selinux.py $(PYLIBDIR)/site-packages/selinux/__init__.py
+	install -m 644 $(SWIGPYOUT) $(PYLIBDIR)/site-packages/selinux/__init__.py
 
 install-rubywrap: rubywrap
 	test -d $(RUBYINSTALL) || install -m 755 -d $(RUBYINSTALL) 
diff --git a/libselinux/src/checkAccess.c b/libselinux/src/checkAccess.c
index 29be16e..8de5747 100644
--- a/libselinux/src/checkAccess.c
+++ b/libselinux/src/checkAccess.c
@@ -10,11 +10,26 @@
 static pthread_once_t once = PTHREAD_ONCE_INIT;
 static int selinux_enabled;
 
+static int avc_reset_callback(uint32_t event __attribute__((unused)),
+		      security_id_t ssid __attribute__((unused)),
+		      security_id_t tsid __attribute__((unused)),
+		      security_class_t tclass __attribute__((unused)),
+		      access_vector_t perms __attribute__((unused)),
+		      access_vector_t *out_retained __attribute__((unused)))
+{
+	flush_class_cache();
+	return 0;
+}
+
 static void avc_init_once(void)
 {
 	selinux_enabled = is_selinux_enabled();
-	if (selinux_enabled == 1)
-		avc_open(NULL, 0);
+	if (selinux_enabled == 1) {
+		if (avc_open(NULL, 0))
+			return;
+		avc_add_callback(avc_reset_callback, AVC_CALLBACK_RESET,
+				 0, 0, 0, 0);
+	}
 }
 
 int selinux_check_access(const char *scon, const char *tcon, const char *class, const char *perm, void *aux) {
@@ -33,9 +48,11 @@
 	if (rc < 0)
 		return rc;
 
-       rc = avc_context_to_sid(tcon, &tcon_id);
-       if (rc < 0)
-	       return rc;
+	rc = avc_context_to_sid(tcon, &tcon_id);
+	if (rc < 0)
+		return rc;
+
+	(void) avc_netlink_check_nb();
 
        sclass = string_to_security_class(class);
        if (sclass == 0) {
diff --git a/libselinux/src/label.c b/libselinux/src/label.c
index 759a3fa..963bfcb 100644
--- a/libselinux/src/label.c
+++ b/libselinux/src/label.c
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <selinux/selinux.h>
 #include "callbacks.h"
 #include "label_internal.h"
@@ -17,7 +18,8 @@
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
 typedef int (*selabel_initfunc)(struct selabel_handle *rec,
-				struct selinux_opt *opts, unsigned nopts);
+				const struct selinux_opt *opts,
+				unsigned nopts);
 
 static selabel_initfunc initfuncs[] = {
 	&selabel_file_init,
@@ -64,15 +66,21 @@
 	return NULL;
 }
 
-struct selabel_sub *selabel_subs_init(const char *path, struct selabel_sub *list)
+struct selabel_sub *selabel_subs_init(const char *path,
+					    struct selabel_sub *list,
+					    struct selabel_digest *digest)
 {
 	char buf[1024];
 	FILE *cfg = fopen(path, "r");
-	struct selabel_sub *sub;
+	struct selabel_sub *sub = NULL;
+	struct stat sb;
 
 	if (!cfg)
 		return list;
 
+	if (fstat(fileno(cfg), &sb) < 0)
+		return list;
+
 	while (fgets_unlocked(buf, sizeof(buf) - 1, cfg)) {
 		char *ptr = NULL;
 		char *src = buf;
@@ -114,6 +122,10 @@
 		sub->next = list;
 		list = sub;
 	}
+
+	if (digest_add_specfile(digest, cfg, NULL, sb.st_size, path) < 0)
+		goto err;
+
 out:
 	fclose(cfg);
 	return list;
@@ -124,11 +136,63 @@
 	goto out;
 }
 
+static inline struct selabel_digest *selabel_is_digest_set
+				    (const struct selinux_opt *opts,
+				    unsigned n,
+				    struct selabel_digest *entry)
+{
+	struct selabel_digest *digest = NULL;
+
+	while (n--) {
+		if (opts[n].type == SELABEL_OPT_DIGEST &&
+					    opts[n].value == (char *)1) {
+			digest = calloc(1, sizeof(*digest));
+			if (!digest)
+				goto err;
+
+			digest->digest = calloc(1, DIGEST_SPECFILE_SIZE + 1);
+			if (!digest->digest)
+				goto err;
+
+			digest->specfile_list = calloc(DIGEST_FILES_MAX,
+							    sizeof(char *));
+			if (!digest->specfile_list)
+				goto err;
+
+			entry = digest;
+			return entry;
+		}
+	}
+	return NULL;
+
+err:
+	free(digest->digest);
+	free(digest->specfile_list);
+	free(digest);
+	return NULL;
+}
+
+static void selabel_digest_fini(struct selabel_digest *ptr)
+{
+	int i;
+
+	free(ptr->digest);
+	free(ptr->hashbuf);
+
+	if (ptr->specfile_list) {
+		for (i = 0; ptr->specfile_list[i]; i++)
+			free(ptr->specfile_list[i]);
+		free(ptr->specfile_list);
+	}
+	free(ptr);
+}
+
 /*
  * Validation functions
  */
 
-static inline int selabel_is_validate_set(struct selinux_opt *opts, unsigned n)
+static inline int selabel_is_validate_set(const struct selinux_opt *opts,
+					  unsigned n)
 {
 	while (n--)
 		if (opts[n].type == SELABEL_OPT_VALIDATE)
@@ -251,7 +315,8 @@
  */
 
 struct selabel_handle *selabel_open(unsigned int backend,
-				    struct selinux_opt *opts, unsigned nopts)
+				    const struct selinux_opt *opts,
+				    unsigned nopts)
 {
 	struct selabel_handle *rec = NULL;
 
@@ -270,8 +335,10 @@
 
 	rec->subs = NULL;
 	rec->dist_subs = NULL;
+	rec->digest = selabel_is_digest_set(opts, nopts, rec->digest);
 
 	if ((*initfuncs[backend])(rec, opts, nopts)) {
+		free(rec->spec_file);
 		free(rec);
 		rec = NULL;
 	}
@@ -366,10 +433,37 @@
 	return *con ? 0 : -1;
 }
 
+enum selabel_cmp_result selabel_cmp(struct selabel_handle *h1,
+				    struct selabel_handle *h2)
+{
+	if (!h1->func_cmp || h1->func_cmp != h2->func_cmp)
+		return SELABEL_INCOMPARABLE;
+
+	return h1->func_cmp(h1, h2);
+}
+
+int selabel_digest(struct selabel_handle *rec,
+				    unsigned char **digest, size_t *digest_len,
+				    char ***specfiles, size_t *num_specfiles)
+{
+	if (!rec->digest) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	*digest = rec->digest->digest;
+	*digest_len = DIGEST_SPECFILE_SIZE;
+	*specfiles = rec->digest->specfile_list;
+	*num_specfiles = rec->digest->specfile_cnt;
+	return 0;
+}
+
 void selabel_close(struct selabel_handle *rec)
 {
 	selabel_subs_fini(rec->subs);
 	selabel_subs_fini(rec->dist_subs);
+	if (rec->digest)
+		selabel_digest_fini(rec->digest);
 	rec->func_close(rec);
 	free(rec->spec_file);
 	free(rec);
diff --git a/libselinux/src/label_android_property.c b/libselinux/src/label_android_property.c
index dadb160..712eecb 100644
--- a/libselinux/src/label_android_property.c
+++ b/libselinux/src/label_android_property.c
@@ -1,5 +1,5 @@
 /*
- * Property Service contexts backend for labeling Android 
+ * Property Service contexts backend for labeling Android
  * property keys
  */
 
@@ -16,7 +16,7 @@
 /* A property security context specification. */
 typedef struct spec {
 	struct selabel_lookup_rec lr;	/* holds contexts for lookup result */
-	char *property_key;	/* property key string */
+	char *property_key;		/* property key string */
 } spec_t;
 
 /* Our stored configuration */
@@ -56,21 +56,23 @@
 	for (ii = 0; ii < data->nspec; ii++) {
 		curr_spec = &spec_arr[ii];
 		for (jj = ii + 1; jj < data->nspec; jj++) {
-			if (!strcmp(spec_arr[jj].property_key, curr_spec->property_key)) {
+			if (!strcmp(spec_arr[jj].property_key,
+					    curr_spec->property_key)) {
 				rc = -1;
 				errno = EINVAL;
-				if (strcmp(spec_arr[jj].lr.ctx_raw, curr_spec->lr.ctx_raw)) {
-					selinux_log(SELINUX_ERROR,
-						    "%s: Multiple different specifications for %s  (%s and %s).\n",
-						    path,
-						    curr_spec->property_key,
-						    spec_arr[jj].lr.ctx_raw,
-						    curr_spec->lr.ctx_raw);
+				if (strcmp(spec_arr[jj].lr.ctx_raw,
+						    curr_spec->lr.ctx_raw)) {
+					selinux_log
+						(SELINUX_ERROR,
+						 "%s: Multiple different specifications for %s  (%s and %s).\n",
+						 path, curr_spec->property_key,
+						 spec_arr[jj].lr.ctx_raw,
+						 curr_spec->lr.ctx_raw);
 				} else {
-					selinux_log(SELINUX_ERROR,
-						    "%s: Multiple same specifications for %s.\n",
-						    path,
-						    curr_spec->property_key);
+					selinux_log
+						(SELINUX_ERROR,
+						 "%s: Multiple same specifications for %s.\n",
+						 path, curr_spec->property_key);
 				}
 			}
 		}
@@ -92,36 +94,29 @@
 	if (items <= 0)
 		return items;
 	if (items != 2) {
-		selinux_log(SELINUX_WARNING,
-			    "%s:  line %u is missing fields, skipping\n", path,
+		selinux_log(SELINUX_ERROR,
+			    "%s:  line %u is missing fields\n", path,
 			    lineno);
-		return 0;
+		free(prop);
+		errno = EINVAL;
+		return -1;
 	}
 
-	if (pass == 1) {
+	if (pass == 0) {
+		free(prop);
+		free(context);
+	} else if (pass == 1) {
 		/* On the second pass, process and store the specification in spec. */
-		spec_arr[nspec].property_key = strdup(prop);
-		if (!spec_arr[nspec].property_key) {
-			selinux_log(SELINUX_WARNING,
-				    "%s:  out of memory at line %u on prop %s\n",
-				    path, lineno, prop);
-			return -1;
-
-		}
-
-		spec_arr[nspec].lr.ctx_raw = strdup(context);
-		if (!spec_arr[nspec].lr.ctx_raw) {
-			selinux_log(SELINUX_WARNING,
-				    "%s:  out of memory at line %u on context %s\n",
-				    path, lineno, context);
-			return -1;
-		}
+		spec_arr[nspec].property_key = prop;
+		spec_arr[nspec].lr.ctx_raw = context;
 
 		if (rec->validating) {
 			if (selabel_validate(rec, &spec_arr[nspec].lr) < 0) {
-				selinux_log(SELINUX_WARNING,
+				selinux_log(SELINUX_ERROR,
 					    "%s:  line %u has invalid context %s\n",
 					    path, lineno, spec_arr[nspec].lr.ctx_raw);
+				errno = EINVAL;
+				return -1;
 			}
 		}
 	}
@@ -130,7 +125,7 @@
 	return 0;
 }
 
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
 		unsigned n)
 {
 	struct saved_data *data = (struct saved_data *)rec->data;
@@ -149,7 +144,7 @@
 			break;
 		}
 
-	if (!path) 
+	if (!path)
 		return -1;
 
 	/* Open the specification file. */
@@ -164,17 +159,18 @@
 
 	/*
 	 * Two passes of the specification file. First is to get the size.
-	 * After the first pass, the spec array is malloced to the appropriate 
-	 * size. Second pass is to populate the spec array and check for 
+	 * After the first pass, the spec array is malloced to the appropriate
+	 * size. Second pass is to populate the spec array and check for
 	 * dups.
 	 */
 	maxnspec = UINT_MAX / sizeof(spec_t);
 	for (pass = 0; pass < 2; pass++) {
 		data->nspec = 0;
 
-		while (fgets(line_buf, sizeof line_buf - 1, fp)
+		while (fgets(line_buf, sizeof(line_buf) - 1, fp)
 		       && data->nspec < maxnspec) {
-			if (process_line(rec, path, line_buf, pass, ++lineno) != 0)
+			if (process_line(rec, path, line_buf, pass, ++lineno)
+									  != 0)
 				goto finish;
 		}
 
@@ -186,7 +182,6 @@
 		}
 
 		if (pass == 0) {
-
 			if (data->nspec == 0) {
 				status = 0;
 				goto finish;
@@ -204,7 +199,12 @@
 
 	qsort(data->spec_arr, data->nspec, sizeof(struct spec), cmp);
 
-	status = 0;
+	status = digest_add_specfile(rec->digest, fp, NULL, sb.st_size, path);
+	if (status)
+		goto finish;
+
+	digest_gen_hash(rec->digest);
+
 finish:
 	fclose(fp);
 	return status;
@@ -234,7 +234,7 @@
 
 static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
 					 const char *key,
-					 int __attribute__ ((unused)) type)
+					 int __attribute__((unused)) type)
 {
 	struct saved_data *data = (struct saved_data *)rec->data;
 	spec_t *spec_arr = data->spec_arr;
@@ -267,12 +267,13 @@
 	return ret;
 }
 
-static void stats(struct selabel_handle __attribute__ ((unused)) * rec)
+static void stats(struct selabel_handle __attribute__((unused)) *rec)
 {
 	selinux_log(SELINUX_WARNING, "'stats' functionality not implemented.\n");
 }
 
-int selabel_property_init(struct selabel_handle *rec, struct selinux_opt *opts,
+int selabel_property_init(struct selabel_handle *rec,
+			  const struct selinux_opt *opts,
 			  unsigned nopts)
 {
 	struct saved_data *data;
diff --git a/libselinux/src/label_db.c b/libselinux/src/label_db.c
index 1b48735..1155bcc 100644
--- a/libselinux/src/label_db.c
+++ b/libselinux/src/label_db.c
@@ -234,7 +234,8 @@
  * selabel_open() handler
  */
 static catalog_t *
-db_init(struct selinux_opt *opts, unsigned nopts, struct selabel_handle *rec)
+db_init(const struct selinux_opt *opts, unsigned nopts,
+			    struct selabel_handle *rec)
 {
 	catalog_t      *catalog;
 	FILE	       *filp;
@@ -243,6 +244,7 @@
 	size_t		line_len = 0;
 	unsigned int	line_num = 0;
 	unsigned int	i;
+	struct stat sb;
 
 	/*
 	 * Initialize catalog data structure
@@ -279,6 +281,12 @@
 		free(catalog);
 		return NULL;
 	}
+	if (fstat(fileno(filp), &sb) < 0)
+		return NULL;
+	if (!S_ISREG(sb.st_mode)) {
+		errno = EINVAL;
+		return NULL;
+	}
 	rec->spec_file = strdup(path);
 
 	/*
@@ -311,6 +319,11 @@
 	}
 	free(line_buf);
 
+	if (digest_add_specfile(rec->digest, filp, NULL, sb.st_size, path) < 0)
+		goto out_error;
+
+	digest_gen_hash(rec->digest);
+
 	fclose(filp);
 
 	return catalog;
@@ -332,7 +345,7 @@
  * Initialize selabel_handle and load the entries of specfile
  */
 int selabel_db_init(struct selabel_handle *rec,
-		    struct selinux_opt *opts, unsigned nopts)
+		    const struct selinux_opt *opts, unsigned nopts)
 {
 	rec->func_close = &db_close;
 	rec->func_lookup = &db_lookup;
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index 60aae66..071d902 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -5,6 +5,7 @@
  * Author : Stephen Smalley <sds@tycho.nsa.gov>
  */
 
+#include <assert.h>
 #include <fcntl.h>
 #include <stdarg.h>
 #include <string.h>
@@ -15,13 +16,11 @@
 #include <limits.h>
 #include <stdint.h>
 #include <pcre.h>
-
-#include <linux/limits.h>
-
+#include <unistd.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
+
 #include "callbacks.h"
 #include "label_internal.h"
 #include "label_file.h"
@@ -72,12 +71,14 @@
 	for (ii = 0; ii < data->nspec; ii++) {
 		curr_spec = &spec_arr[ii];
 		for (jj = ii + 1; jj < data->nspec; jj++) {
-			if ((!strcmp(spec_arr[jj].regex_str, curr_spec->regex_str))
+			if ((!strcmp(spec_arr[jj].regex_str,
+				curr_spec->regex_str))
 			    && (!spec_arr[jj].mode || !curr_spec->mode
 				|| spec_arr[jj].mode == curr_spec->mode)) {
 				rc = -1;
 				errno = EINVAL;
-				if (strcmp(spec_arr[jj].lr.ctx_raw, curr_spec->lr.ctx_raw)) {
+				if (strcmp(spec_arr[jj].lr.ctx_raw,
+					    curr_spec->lr.ctx_raw)) {
 					COMPAT_LOG
 						(SELINUX_ERROR,
 						 "%s: Multiple different specifications for %s  (%s and %s).\n",
@@ -96,136 +97,9 @@
 	return rc;
 }
 
-static int compile_regex(struct saved_data *data, struct spec *spec, const char **errbuf)
-{
-	const char *tmperrbuf;
-	char *reg_buf, *anchored_regex, *cp;
-	struct stem *stem_arr = data->stem_arr;
-	size_t len;
-	int erroff;
-
-	if (spec->regcomp)
-		return 0; /* already done */
-
-	/* Skip the fixed stem. */
-	reg_buf = spec->regex_str;
-	if (spec->stem_id >= 0)
-		reg_buf += stem_arr[spec->stem_id].len;
-
-	/* Anchor the regular expression. */
-	len = strlen(reg_buf);
-	cp = anchored_regex = malloc(len + 3);
-	if (!anchored_regex)
-		return -1;
-
-	/* Create ^...$ regexp.  */
-	*cp++ = '^';
-	cp = mempcpy(cp, reg_buf, len);
-	*cp++ = '$';
-	*cp = '\0';
-
-	/* Compile the regular expression. */
-	spec->regex = pcre_compile(anchored_regex, PCRE_DOTALL, &tmperrbuf, &erroff, NULL);
-	free(anchored_regex);
-	if (!spec->regex) {
-		if (errbuf)
-			*errbuf=tmperrbuf;
-		return -1;
-	}
-
-	spec->sd = pcre_study(spec->regex, 0, &tmperrbuf);
-	if (!spec->sd && tmperrbuf) {
-		if (errbuf)
-			*errbuf=tmperrbuf;
-		return -1;
-	}
-
-	/* Done. */
-	spec->regcomp = 1;
-
-	return 0;
-}
-
-static int process_line(struct selabel_handle *rec,
-			const char *path, const char *prefix,
-			char *line_buf, unsigned lineno)
-{
-	int items, len, rc;
-	char *regex = NULL, *type = NULL, *context = NULL;
-	struct saved_data *data = (struct saved_data *)rec->data;
-	struct spec *spec_arr;
-	unsigned int nspec = data->nspec;
-	const char *errbuf = NULL;
-
-	items = read_spec_entries(line_buf, 3, &regex, &type, &context);
-	if (items <= 0)
-		return items;
-
-	if (items < 2) {
-		COMPAT_LOG(SELINUX_WARNING,
-			    "%s:  line %u is missing fields, skipping\n", path,
-			    lineno);
-		if (items == 1)
-			free(regex);
-		return 0;
-	} else if (items == 2) {
-		/* The type field is optional. */
-		free(context);
-		context = type;
-		type = 0;
-	}
-
-	len = get_stem_from_spec(regex);
-	if (len && prefix && strncmp(prefix, regex, len)) {
-		/* Stem of regex does not match requested prefix, discard. */
-		free(regex);
-		free(type);
-		free(context);
-		return 0;
-	}
-
-	rc = grow_specs(data);
-	if (rc)
-		return rc;
-
-	spec_arr = data->spec_arr;
-
-	/* process and store the specification in spec. */
-	spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
-	spec_arr[nspec].regex_str = regex;
-	if (rec->validating && compile_regex(data, &spec_arr[nspec], &errbuf)) {
-		COMPAT_LOG(SELINUX_WARNING, "%s:  line %u has invalid regex %s:  %s\n",
-			   path, lineno, regex, (errbuf ? errbuf : "out of memory"));
-	}
-
-	/* Convert the type string to a mode format */
-	spec_arr[nspec].type_str = type;
-	spec_arr[nspec].mode = 0;
-	if (type) {
-		mode_t mode = string_to_mode(type);
-		if (mode == (mode_t)-1) {
-			COMPAT_LOG(SELINUX_WARNING, "%s:  line %u has invalid file type %s\n",
-				   path, lineno, type);
-			mode = 0;
-		}
-		spec_arr[nspec].mode = mode;
-	}
-
-	spec_arr[nspec].lr.ctx_raw = context;
-
-	/* Determine if specification has
-	 * any meta characters in the RE */
-	spec_hasMetaChars(&spec_arr[nspec]);
-
-	if (strcmp(context, "<<none>>") && rec->validating)
-		compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
-
-	data->nspec = ++nspec;
-
-	return 0;
-}
-
-static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *sb)
+static int load_mmap(struct selabel_handle *rec, const char *path,
+				    struct stat *sb, bool isbinary,
+				    struct selabel_digest *digest)
 {
 	struct saved_data *data = (struct saved_data *)rec->data;
 	char mmap_path[PATH_MAX + 1];
@@ -239,9 +113,16 @@
 	uint32_t i, magic, version;
 	uint32_t entry_len, stem_map_len, regex_array_len;
 
-	rc = snprintf(mmap_path, sizeof(mmap_path), "%s.bin", path);
-	if (rc >= (int)sizeof(mmap_path))
-		return -1;
+	if (isbinary) {
+		len = strlen(path);
+		if (len >= sizeof(mmap_path))
+			return -1;
+		strcpy(mmap_path, path);
+	} else {
+		rc = snprintf(mmap_path, sizeof(mmap_path), "%s.bin", path);
+		if (rc >= (int)sizeof(mmap_path))
+			return -1;
+	}
 
 	mmapfd = open(mmap_path, O_RDONLY | O_CLOEXEC);
 	if (mmapfd < 0)
@@ -259,12 +140,6 @@
 		return -1;
 	}
 
-	if (mmap_stat.st_mtime == sb->st_mtime &&
-	    mmap_stat.st_mtim.tv_nsec < sb->st_mtim.tv_nsec) {
-		close(mmapfd);
-		return -1;
-	}
-
 	/* ok, read it in... */
 	len = mmap_stat.st_size;
 	len += (sysconf(_SC_PAGE_SIZE) - 1);
@@ -285,8 +160,8 @@
 	}
 
 	/* save where we mmap'd the file to cleanup on close() */
-	mmap_area->addr = addr;
-	mmap_area->len = len;
+	mmap_area->addr = mmap_area->next_addr = addr;
+	mmap_area->len = mmap_area->next_len = len;
 	mmap_area->next = data->mmap_areas;
 	data->mmap_areas = mmap_area;
 
@@ -357,7 +232,7 @@
 
 		/* Check for stem_len wrap around. */
 		if (stem_len < UINT32_MAX) {
-			buf = (char *)mmap_area->addr;
+			buf = (char *)mmap_area->next_addr;
 			/* Check if over-run before null check. */
 			rc = next_entry(NULL, mmap_area, (stem_len + 1));
 			if (rc < 0)
@@ -395,7 +270,7 @@
 	for (i = 0; i < regex_array_len; i++) {
 		struct spec *spec;
 		int32_t stem_id, meta_chars;
-		uint32_t mode = 0;
+		uint32_t mode = 0, prefix_len = 0;
 
 		rc = grow_specs(data);
 		if (rc < 0)
@@ -428,6 +303,14 @@
 		}
 		spec->lr.ctx_raw = str_buf;
 
+		if (strcmp(spec->lr.ctx_raw, "<<none>>") && rec->validating) {
+			if (selabel_validate(rec, &spec->lr) < 0) {
+				selinux_log(SELINUX_ERROR,
+					    "%s: context %s is invalid\n", mmap_path, spec->lr.ctx_raw);
+				goto err;
+			}
+		}
+
 		/* Process regex string */
 		rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t));
 		if (rc < 0 || !entry_len) {
@@ -435,7 +318,7 @@
 			goto err;
 		}
 
-		spec->regex_str = (char *)mmap_area->addr;
+		spec->regex_str = (char *)mmap_area->next_addr;
 		rc = next_entry(NULL, mmap_area, entry_len);
 		if (rc < 0)
 			goto err;
@@ -460,7 +343,7 @@
 		if (rc < 0)
 			goto err;
 
-		if (stem_id < 0 || stem_id >= stem_map_len)
+		if (stem_id < 0 || stem_id >= (int32_t)stem_map_len)
 			spec->stem_id = -1;
 		 else
 			spec->stem_id = stem_map[stem_id];
@@ -471,6 +354,15 @@
 			goto err;
 
 		spec->hasMetaChars = meta_chars;
+		/* and prefix length for use by selabel_lookup_best_match */
+		if (version >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN) {
+			rc = next_entry(&prefix_len, mmap_area,
+					    sizeof(uint32_t));
+			if (rc < 0)
+				goto err;
+
+			spec->prefix_len = prefix_len;
+		}
 
 		/* Process regex and study_data entries */
 		rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t));
@@ -478,7 +370,7 @@
 			rc = -1;
 			goto err;
 		}
-		spec->regex = (pcre *)mmap_area->addr;
+		spec->regex = (pcre *)mmap_area->next_addr;
 		rc = next_entry(NULL, mmap_area, entry_len);
 		if (rc < 0)
 			goto err;
@@ -496,7 +388,7 @@
 			rc = -1;
 			goto err;
 		}
-		spec->lsd.study_data = (void *)mmap_area->addr;
+		spec->lsd.study_data = (void *)mmap_area->next_addr;
 		spec->lsd.flags |= PCRE_EXTRA_STUDY_DATA;
 		rc = next_entry(NULL, mmap_area, entry_len);
 		if (rc < 0)
@@ -512,27 +404,36 @@
 
 		data->nspec++;
 	}
-	/* win */
-	rc = 0;
+
+	rc = digest_add_specfile(digest, NULL, addr, mmap_stat.st_size,
+								    mmap_path);
+	if (rc)
+		goto err;
+
 err:
 	free(stem_map);
 
 	return rc;
 }
 
-static int process_file(const char *path, const char *suffix, struct selabel_handle *rec, const char *prefix)
+static int process_file(const char *path, const char *suffix,
+			  struct selabel_handle *rec,
+			  const char *prefix, struct selabel_digest *digest)
 {
 	FILE *fp;
 	struct stat sb;
 	unsigned int lineno;
-	size_t line_len;
+	size_t line_len = 0;
 	char *line_buf = NULL;
 	int rc;
 	char stack_path[PATH_MAX + 1];
+	bool isbinary = false;
+	uint32_t magic;
 
 	/* append the path suffix if we have one */
 	if (suffix) {
-		rc = snprintf(stack_path, sizeof(stack_path), "%s.%s", path, suffix);
+		rc = snprintf(stack_path, sizeof(stack_path),
+					    "%s.%s", path, suffix);
 		if (rc >= (int)sizeof(stack_path)) {
 			errno = ENAMETOOLONG;
 			return -1;
@@ -541,38 +442,74 @@
 	}
 
 	/* Open the specification file. */
-	if ((fp = fopen(path, "r")) == NULL)
-		return -1;
-	__fsetlocking(fp, FSETLOCKING_BYCALLER);
+	fp = fopen(path, "r");
+	if (fp) {
+		__fsetlocking(fp, FSETLOCKING_BYCALLER);
 
-	if (fstat(fileno(fp), &sb) < 0)
-		return -1;
-	if (!S_ISREG(sb.st_mode)) {
-		errno = EINVAL;
-		return -1;
+		if (fstat(fileno(fp), &sb) < 0)
+			return -1;
+		if (!S_ISREG(sb.st_mode)) {
+			errno = EINVAL;
+			return -1;
+		}
+
+		magic = 0;
+		if (fread(&magic, sizeof magic, 1, fp) != 1) {
+			if (ferror(fp)) {
+				errno = EINVAL;
+				fclose(fp);
+				return -1;
+			}
+			clearerr(fp);
+		}
+
+		if (magic == SELINUX_MAGIC_COMPILED_FCONTEXT) {
+			/* file_contexts.bin format */
+			fclose(fp);
+			fp = NULL;
+			isbinary = true;
+		} else {
+			rewind(fp);
+		}
+	} else {
+		/*
+		 * Text file does not exist, so clear the timestamp
+		 * so that we will always pass the timestamp comparison
+		 * with the bin file in load_mmap().
+		 */
+		sb.st_mtime = 0;
 	}
 
-	rc = load_mmap(rec, path, &sb);
+	rc = load_mmap(rec, path, &sb, isbinary, digest);
 	if (rc == 0)
 		goto out;
 
+	if (!fp)
+		return -1; /* no text or bin file */
+
 	/*
-	 * The do detailed validation of the input and fill the spec array
+	 * Then do detailed validation of the input and fill the spec array
 	 */
 	lineno = 0;
+	rc = 0;
 	while (getline(&line_buf, &line_len, fp) > 0) {
 		rc = process_line(rec, path, prefix, line_buf, ++lineno);
 		if (rc)
-			return rc;
+			goto out;
 	}
+
+	rc = digest_add_specfile(digest, fp, NULL, sb.st_size, path);
+
 out:
 	free(line_buf);
-	fclose(fp);
-
-	return 0;
+	if (fp)
+		fclose(fp);
+	return rc;
 }
 
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static void closef(struct selabel_handle *rec);
+
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
 		unsigned n)
 {
 	struct saved_data *data = (struct saved_data *)rec->data;
@@ -597,22 +534,27 @@
 
 	/* Process local and distribution substitution files */
 	if (!path) {
-		rec->dist_subs = selabel_subs_init(selinux_file_context_subs_dist_path(), rec->dist_subs);
-		rec->subs = selabel_subs_init(selinux_file_context_subs_path(), rec->subs);
+		rec->dist_subs =
+		    selabel_subs_init(selinux_file_context_subs_dist_path(),
+		    rec->dist_subs, rec->digest);
+		rec->subs = selabel_subs_init(selinux_file_context_subs_path(),
+		    rec->subs, rec->digest);
 		path = selinux_file_context_path();
 	} else {
 		snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path);
-		rec->dist_subs = selabel_subs_init(subs_file, rec->dist_subs);
+		rec->dist_subs = selabel_subs_init(subs_file, rec->dist_subs,
+							    rec->digest);
 		snprintf(subs_file, sizeof(subs_file), "%s.subs", path);
-		rec->subs = selabel_subs_init(subs_file, rec->subs);
+		rec->subs = selabel_subs_init(subs_file, rec->subs,
+							    rec->digest);
 	}
 
 	rec->spec_file = strdup(path);
 
-	/* 
+	/*
 	 * The do detailed validation of the input and fill the spec array
 	 */
-	status = process_file(path, NULL, rec, prefix);
+	status = process_file(path, NULL, rec, prefix, rec->digest);
 	if (status)
 		goto finish;
 
@@ -623,21 +565,25 @@
 	}
 
 	if (!baseonly) {
-		status = process_file(path, "homedirs", rec, prefix);
+		status = process_file(path, "homedirs", rec, prefix,
+							    rec->digest);
 		if (status && errno != ENOENT)
 			goto finish;
 
-		status = process_file(path, "local", rec, prefix);
+		status = process_file(path, "local", rec, prefix,
+							    rec->digest);
 		if (status && errno != ENOENT)
 			goto finish;
 	}
 
+	digest_gen_hash(rec->digest);
+
 	status = sort_specs(data);
 
-	status = 0;
 finish:
 	if (status)
-		free(data->spec_arr);
+		closef(rec);
+
 	return status;
 }
 
@@ -731,7 +677,7 @@
 	if (partial)
 		pcre_options |= PCRE_PARTIAL_SOFT;
 
-	/* 
+	/*
 	 * Check for matching specifications in reverse order, so that
 	 * the last matching specification is used.
 	 */
@@ -857,6 +803,96 @@
 	return lr;
 }
 
+static enum selabel_cmp_result incomp(struct spec *spec1, struct spec *spec2, const char *reason, int i, int j)
+{
+	selinux_log(SELINUX_INFO,
+		    "selabel_cmp: mismatched %s on entry %d: (%s, %x, %s) vs entry %d: (%s, %x, %s)\n",
+		    reason,
+		    i, spec1->regex_str, spec1->mode, spec1->lr.ctx_raw,
+		    j, spec2->regex_str, spec2->mode, spec2->lr.ctx_raw);
+	return SELABEL_INCOMPARABLE;
+}
+
+static enum selabel_cmp_result cmp(struct selabel_handle *h1,
+				   struct selabel_handle *h2)
+{
+	struct saved_data *data1 = (struct saved_data *)h1->data;
+	struct saved_data *data2 = (struct saved_data *)h2->data;
+	unsigned int i, nspec1 = data1->nspec, j, nspec2 = data2->nspec;
+	struct spec *spec_arr1 = data1->spec_arr, *spec_arr2 = data2->spec_arr;
+	struct stem *stem_arr1 = data1->stem_arr, *stem_arr2 = data2->stem_arr;
+	bool skipped1 = false, skipped2 = false;
+
+	i = 0;
+	j = 0;
+	while (i < nspec1 && j < nspec2) {
+		struct spec *spec1 = &spec_arr1[i];
+		struct spec *spec2 = &spec_arr2[j];
+
+		/*
+		 * Because sort_specs() moves exact pathnames to the
+		 * end, we might need to skip over additional regex
+		 * entries that only exist in one of the configurations.
+		 */
+		if (!spec1->hasMetaChars && spec2->hasMetaChars) {
+			j++;
+			skipped2 = true;
+			continue;
+		}
+
+		if (spec1->hasMetaChars && !spec2->hasMetaChars) {
+			i++;
+			skipped1 = true;
+			continue;
+		}
+
+		if (spec1->regcomp && spec2->regcomp) {
+			size_t len1, len2;
+			int rc;
+
+			rc = pcre_fullinfo(spec1->regex, NULL, PCRE_INFO_SIZE, &len1);
+			assert(rc == 0);
+			rc = pcre_fullinfo(spec2->regex, NULL, PCRE_INFO_SIZE, &len2);
+			assert(rc == 0);
+			if (len1 != len2 ||
+			    memcmp(spec1->regex, spec2->regex, len1))
+				return incomp(spec1, spec2, "regex", i, j);
+		} else {
+			if (strcmp(spec1->regex_str, spec2->regex_str))
+				return incomp(spec1, spec2, "regex_str", i, j);
+		}
+
+		if (spec1->mode != spec2->mode)
+			return incomp(spec1, spec2, "mode", i, j);
+
+		if (spec1->stem_id == -1 && spec2->stem_id != -1)
+			return incomp(spec1, spec2, "stem_id", i, j);
+		if (spec2->stem_id == -1 && spec1->stem_id != -1)
+			return incomp(spec1, spec2, "stem_id", i, j);
+		if (spec1->stem_id != -1 && spec2->stem_id != -1) {
+			struct stem *stem1 = &stem_arr1[spec1->stem_id];
+			struct stem *stem2 = &stem_arr2[spec2->stem_id];
+			if (stem1->len != stem2->len ||
+			    strncmp(stem1->buf, stem2->buf, stem1->len))
+				return incomp(spec1, spec2, "stem", i, j);
+		}
+
+		if (strcmp(spec1->lr.ctx_raw, spec2->lr.ctx_raw))
+			return incomp(spec1, spec2, "ctx_raw", i, j);
+
+		i++;
+		j++;
+	}
+
+	if ((skipped1 || i < nspec1) && !skipped2)
+		return SELABEL_SUPERSET;
+	if ((skipped2 || j < nspec2) && !skipped1)
+		return SELABEL_SUBSET;
+	if (skipped1 && skipped2)
+		return SELABEL_INCOMPARABLE;
+	return SELABEL_EQUAL;
+}
+
 
 static void stats(struct selabel_handle *rec)
 {
@@ -882,8 +918,9 @@
 	}
 }
 
-int selabel_file_init(struct selabel_handle *rec, struct selinux_opt *opts,
-		      unsigned nopts)
+int selabel_file_init(struct selabel_handle *rec,
+				    const struct selinux_opt *opts,
+				    unsigned nopts)
 {
 	struct saved_data *data;
 
@@ -898,6 +935,7 @@
 	rec->func_lookup = &lookup;
 	rec->func_partial_match = &partial_match;
 	rec->func_lookup_best_match = &lookup_best_match;
+	rec->func_cmp = &cmp;
 
 	return init(rec, opts, nopts);
 }
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index a8d1e51..beb1fc2 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -3,6 +3,7 @@
 
 #include <sys/stat.h>
 
+#include "callbacks.h"
 #include "label_internal.h"
 
 #define SELINUX_MAGIC_COMPILED_FCONTEXT	0xf97cff8a
@@ -11,10 +12,11 @@
 #define SELINUX_COMPILED_FCONTEXT_NOPCRE_VERS	1
 #define SELINUX_COMPILED_FCONTEXT_PCRE_VERS	2
 #define SELINUX_COMPILED_FCONTEXT_MODE		3
+#define SELINUX_COMPILED_FCONTEXT_PREFIX_LEN	4
 
-#define SELINUX_COMPILED_FCONTEXT_MAX_VERS	SELINUX_COMPILED_FCONTEXT_MODE
+#define SELINUX_COMPILED_FCONTEXT_MAX_VERS	SELINUX_COMPILED_FCONTEXT_PREFIX_LEN
 
-/* Prior to verison 8.20, libpcre did not have pcre_free_study() */
+/* Prior to version 8.20, libpcre did not have pcre_free_study() */
 #if (PCRE_MAJOR < 8 || (PCRE_MAJOR == 8 && PCRE_MINOR < 20))
 #define pcre_free_study  pcre_free
 #endif
@@ -47,8 +49,10 @@
 
 /* Where we map the file in during selabel_open() */
 struct mmap_area {
-	void *addr;	/* Start of area - gets incremented by next_entry() */
-	size_t len;	/* Length - gets decremented by next_entry() */
+	void *addr;	/* Start addr + len used to release memory at close */
+	size_t len;
+	void *next_addr;	/* Incremented by next_entry() */
+	size_t next_len;	/* Decremented by next_entry() */
 	struct mmap_area *next;
 };
 
@@ -147,6 +151,7 @@
 	end = c + len;
 
 	spec->hasMetaChars = 0;
+	spec->prefix_len = len;
 
 	/* Look at each character in the RE specification string for a
 	 * meta character. Return when any meta character reached. */
@@ -163,6 +168,7 @@
 		case '(':
 		case '{':
 			spec->hasMetaChars = 1;
+			spec->prefix_len = c - spec->regex_str;
 			return;
 		case '\\':	/* skip the next character */
 			c++;
@@ -173,7 +179,6 @@
 		}
 		c++;
 	}
-	return;
 }
 
 /* Move exact pathname specifications to the end. */
@@ -200,9 +205,9 @@
 	}
 
 	/*
-	 * now the exact pathnames are at the end, but they are in the reverse order.
-	 * since 'front' is now the first of the 'exact' we can run that part of the
-	 * array switching the front and back element.
+	 * now the exact pathnames are at the end, but they are in the reverse
+	 * order. Since 'front' is now the first of the 'exact' we can run
+	 * that part of the array switching the front and back element.
 	 */
 	back = data->nspec - 1;
 	while (front < back) {
@@ -242,7 +247,8 @@
 /*
  * return the stemid given a string and a length
  */
-static inline int find_stem(struct saved_data *data, const char *buf, int stem_len)
+static inline int find_stem(struct saved_data *data, const char *buf,
+						    int stem_len)
 {
 	int i;
 
@@ -272,6 +278,7 @@
 	}
 	data->stem_arr[num].len = stem_len;
 	data->stem_arr[num].buf = buf;
+	data->stem_arr[num].from_mmap = 0;
 	data->num_stems++;
 
 	return num;
@@ -306,14 +313,161 @@
  * current buffer). */
 static inline int next_entry(void *buf, struct mmap_area *fp, size_t bytes)
 {
-	if (bytes > fp->len)
+	if (bytes > fp->next_len)
 		return -1;
 
 	if (buf)
-		memcpy(buf, fp->addr, bytes);
+		memcpy(buf, fp->next_addr, bytes);
 
-	fp->addr = (char *)fp->addr + bytes;
-	fp->len -= bytes;
+	fp->next_addr = (char *)fp->next_addr + bytes;
+	fp->next_len -= bytes;
+	return 0;
+}
+
+static inline int compile_regex(struct saved_data *data, struct spec *spec,
+					    const char **errbuf)
+{
+	const char *tmperrbuf;
+	char *reg_buf, *anchored_regex, *cp;
+	struct stem *stem_arr = data->stem_arr;
+	size_t len;
+	int erroff;
+
+	if (spec->regcomp)
+		return 0; /* already done */
+
+	/* Skip the fixed stem. */
+	reg_buf = spec->regex_str;
+	if (spec->stem_id >= 0)
+		reg_buf += stem_arr[spec->stem_id].len;
+
+	/* Anchor the regular expression. */
+	len = strlen(reg_buf);
+	cp = anchored_regex = malloc(len + 3);
+	if (!anchored_regex)
+		return -1;
+
+	/* Create ^...$ regexp.  */
+	*cp++ = '^';
+	memcpy(cp, reg_buf, len);
+	cp += len;
+	*cp++ = '$';
+	*cp = '\0';
+
+	/* Compile the regular expression. */
+	spec->regex = pcre_compile(anchored_regex, PCRE_DOTALL, &tmperrbuf,
+						    &erroff, NULL);
+	free(anchored_regex);
+	if (!spec->regex) {
+		if (errbuf)
+			*errbuf = tmperrbuf;
+		return -1;
+	}
+
+	spec->sd = pcre_study(spec->regex, 0, &tmperrbuf);
+	if (!spec->sd && tmperrbuf) {
+		if (errbuf)
+			*errbuf = tmperrbuf;
+		return -1;
+	}
+
+	/* Done. */
+	spec->regcomp = 1;
+
+	return 0;
+}
+
+/* This service is used by label_file.c process_file() and
+ * utils/sefcontext_compile.c */
+static inline int process_line(struct selabel_handle *rec,
+			const char *path, const char *prefix,
+			char *line_buf, unsigned lineno)
+{
+	int items, len, rc;
+	char *regex = NULL, *type = NULL, *context = NULL;
+	struct saved_data *data = (struct saved_data *)rec->data;
+	struct spec *spec_arr;
+	unsigned int nspec = data->nspec;
+	const char *errbuf = NULL;
+
+	items = read_spec_entries(line_buf, 3, &regex, &type, &context);
+	if (items <= 0)
+		return items;
+
+	if (items < 2) {
+		COMPAT_LOG(SELINUX_ERROR,
+			    "%s:  line %u is missing fields\n", path,
+			    lineno);
+		if (items == 1)
+			free(regex);
+		errno = EINVAL;
+		return -1;
+	} else if (items == 2) {
+		/* The type field is optional. */
+		context = type;
+		type = 0;
+	}
+
+	len = get_stem_from_spec(regex);
+	if (len && prefix && strncmp(prefix, regex, len)) {
+		/* Stem of regex does not match requested prefix, discard. */
+		free(regex);
+		free(type);
+		free(context);
+		return 0;
+	}
+
+	rc = grow_specs(data);
+	if (rc)
+		return rc;
+
+	spec_arr = data->spec_arr;
+
+	/* process and store the specification in spec. */
+	spec_arr[nspec].stem_id = find_stem_from_spec(data, regex);
+	spec_arr[nspec].regex_str = regex;
+
+	spec_arr[nspec].type_str = type;
+	spec_arr[nspec].mode = 0;
+
+	spec_arr[nspec].lr.ctx_raw = context;
+
+	/*
+	 * bump data->nspecs to cause closef() to cover it in its free
+	 * but do not bump nspec since it's used below.
+	 */
+	data->nspec++;
+
+	if (rec->validating &&
+			    compile_regex(data, &spec_arr[nspec], &errbuf)) {
+		COMPAT_LOG(SELINUX_ERROR,
+			   "%s:  line %u has invalid regex %s:  %s\n",
+			   path, lineno, regex,
+			   (errbuf ? errbuf : "out of memory"));
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (type) {
+		mode_t mode = string_to_mode(type);
+
+		if (mode == (mode_t)-1) {
+			COMPAT_LOG(SELINUX_ERROR,
+				   "%s:  line %u has invalid file type %s\n",
+				   path, lineno, type);
+			errno = EINVAL;
+			return -1;
+		}
+		spec_arr[nspec].mode = mode;
+	}
+
+	/* Determine if specification has
+	 * any meta characters in the RE */
+	spec_hasMetaChars(&spec_arr[nspec]);
+
+	if (strcmp(context, "<<none>>") && rec->validating)
+		compat_validate(rec, &spec_arr[nspec].lr, path, lineno);
+
 	return 0;
 }
 
diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h
index 0e582b6..cefa80b 100644
--- a/libselinux/src/label_internal.h
+++ b/libselinux/src/label_internal.h
@@ -10,23 +10,30 @@
 
 #include <stdlib.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <selinux/selinux.h>
 #include <selinux/label.h>
 #include "dso.h"
+#include "sha1.h"
 
 /*
  * Installed backends
  */
-int selabel_file_init(struct selabel_handle *rec, struct selinux_opt *opts,
-		      unsigned nopts) hidden;
-int selabel_media_init(struct selabel_handle *rec, struct selinux_opt *opts,
-		      unsigned nopts) hidden;
-int selabel_x_init(struct selabel_handle *rec, struct selinux_opt *opts,
-		   unsigned nopts) hidden;
+int selabel_file_init(struct selabel_handle *rec,
+			    const struct selinux_opt *opts,
+			    unsigned nopts) hidden;
+int selabel_media_init(struct selabel_handle *rec,
+			    const struct selinux_opt *opts,
+			    unsigned nopts) hidden;
+int selabel_x_init(struct selabel_handle *rec,
+			    const struct selinux_opt *opts,
+			    unsigned nopts) hidden;
 int selabel_db_init(struct selabel_handle *rec,
-		    struct selinux_opt *opts, unsigned nopts) hidden;
+			    const struct selinux_opt *opts,
+			    unsigned nopts) hidden;
 int selabel_property_init(struct selabel_handle *rec,
-			  struct selinux_opt *opts, unsigned nopts) hidden;
+			    const struct selinux_opt *opts,
+			    unsigned nopts) hidden;
 
 /*
  * Labeling internal structures
@@ -38,8 +45,31 @@
 	struct selabel_sub *next;
 };
 
+/*
+ * Calculate an SHA1 hash of all the files used to build the specs.
+ * The hash value is held in rec->digest if SELABEL_OPT_DIGEST set. To
+ * calculate the hash the hashbuf will hold a concatenation of all the files
+ * used. This is released once the value has been calculated.
+ */
+#define DIGEST_SPECFILE_SIZE SHA1_HASH_SIZE
+#define DIGEST_FILES_MAX 8
+struct selabel_digest {
+	unsigned char *digest;	/* SHA1 digest of specfiles */
+	unsigned char *hashbuf;	/* buffer to hold specfiles */
+	size_t hashbuf_size;	/* buffer size */
+	size_t specfile_cnt;	/* how many specfiles processed */
+	char **specfile_list;	/* and their names */
+};
+
+extern int digest_add_specfile(struct selabel_digest *digest, FILE *fp,
+						    char *from_addr,
+						    size_t buf_len,
+						    const char *path);
+extern void digest_gen_hash(struct selabel_digest *digest);
+
 extern struct selabel_sub *selabel_subs_init(const char *path,
-					     struct selabel_sub *list);
+				    struct selabel_sub *list,
+				    struct selabel_digest *digest);
 
 struct selabel_lookup_rec {
 	char * ctx_raw;
@@ -63,6 +93,8 @@
 						    const char *key,
 						    const char **aliases,
 						    int type);
+	enum selabel_cmp_result (*func_cmp)(struct selabel_handle *h1,
+					    struct selabel_handle *h2);
 
 	/* supports backend-specific state information */
 	void *data;
@@ -76,6 +108,8 @@
 	/* substitution support */
 	struct selabel_sub *dist_subs;
 	struct selabel_sub *subs;
+	/* ptr to SHA1 hash information if SELABEL_OPT_DIGEST set */
+	struct selabel_digest *digest;
 };
 
 /*
@@ -90,7 +124,7 @@
  */
 extern int myprintf_compat;
 extern void __attribute__ ((format(printf, 1, 2)))
-(*myprintf) (const char *fmt,...);
+(*myprintf) (const char *fmt, ...);
 
 #define COMPAT_LOG(type, fmt...) if (myprintf_compat)	  \
 		myprintf(fmt);				  \
diff --git a/libselinux/src/label_media.c b/libselinux/src/label_media.c
index a09486b..622741b 100644
--- a/libselinux/src/label_media.c
+++ b/libselinux/src/label_media.c
@@ -67,7 +67,7 @@
 	return 0;
 }
 
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
 		unsigned n)
 {
 	FILE *fp;
@@ -136,7 +136,12 @@
 	}
 	free(line_buf);
 
-	status = 0;
+	status = digest_add_specfile(rec->digest, fp, NULL, sb.st_size, path);
+	if (status)
+		goto finish;
+
+	digest_gen_hash(rec->digest);
+
 finish:
 	fclose(fp);
 	return status;
@@ -161,7 +166,7 @@
 	if (spec_arr)
 	    free(spec_arr);
 
-	memset(data, 0, sizeof(*data));
+	free(data);
 }
 
 static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
@@ -201,8 +206,9 @@
 		  data->nspec, total);
 }
 
-int selabel_media_init(struct selabel_handle *rec, struct selinux_opt *opts,
-		       unsigned nopts)
+int selabel_media_init(struct selabel_handle *rec,
+				    const struct selinux_opt *opts,
+				    unsigned nopts)
 {
 	struct saved_data *data;
 
diff --git a/libselinux/src/label_support.c b/libselinux/src/label_support.c
index 7464f43..324dc51 100644
--- a/libselinux/src/label_support.c
+++ b/libselinux/src/label_support.c
@@ -8,6 +8,8 @@
 #include <stdarg.h>
 #include <ctype.h>
 #include <string.h>
+#include <stdio.h>
+#include <errno.h>
 #include "label_internal.h"
 
 /*
@@ -15,11 +17,8 @@
  * replace sscanf to read entries from spec files. The file and
  * property services now use these.
  */
-
-/* Read an entry from a spec file (e.g. file_contexts) */
-static inline int read_spec_entry(char **entry, char **ptr)
+static inline int read_spec_entry(char **entry, char **ptr, int *len)
 {
-	int entry_len = 0;
 	*entry = NULL;
 	char *tmp_buf = NULL;
 
@@ -27,15 +26,18 @@
 		(*ptr)++;
 
 	tmp_buf = *ptr;
+	*len = 0;
 
 	while (!isspace(**ptr) && **ptr != '\0') {
 		(*ptr)++;
-		entry_len++;
+		(*len)++;
 	}
 
-	*entry = strndup(tmp_buf, entry_len);
-	if (!*entry)
-		return -1;
+	if (*len) {
+		*entry = strndup(tmp_buf, *len);
+		if (!*entry)
+			return -1;
+	}
 
 	return 0;
 }
@@ -48,15 +50,20 @@
  *
  * This function calls read_spec_entry() to do the actual string processing.
  */
-int read_spec_entries(char *line_buf, int num_args, ...)
+int hidden read_spec_entries(char *line_buf, int num_args, ...)
 {
 	char **spec_entry, *buf_p;
-	int len, rc, items;
+	int len, rc, items, entry_len = 0;
 	va_list ap;
 
 	len = strlen(line_buf);
 	if (line_buf[len - 1] == '\n')
 		line_buf[len - 1] = '\0';
+	else
+		/* Handle case if line not \n terminated by bumping
+		 * the len for the check below (as the line is NUL
+		 * terminated by getline(3)) */
+		len++;
 
 	buf_p = line_buf;
 	while (isspace(*buf_p))
@@ -69,7 +76,8 @@
 	/* Process the spec file entries */
 	va_start(ap, num_args);
 
-	for (items = 0; items < num_args; items++) {
+	items = 0;
+	while (items < num_args) {
 		spec_entry = va_arg(ap, char **);
 
 		if (len - 1 == buf_p - line_buf) {
@@ -77,12 +85,93 @@
 			return items;
 		}
 
-		rc = read_spec_entry(spec_entry, &buf_p);
+		rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
 		if (rc < 0) {
 			va_end(ap);
 			return rc;
 		}
+		if (entry_len)
+			items++;
 	}
 	va_end(ap);
 	return items;
 }
+
+/* Once all the specfiles are in the hash_buf, generate the hash. */
+void hidden digest_gen_hash(struct selabel_digest *digest)
+{
+	Sha1Context context;
+
+	/* If SELABEL_OPT_DIGEST not set then just return */
+	if (!digest)
+		return;
+
+	Sha1Initialise(&context);
+	Sha1Update(&context, digest->hashbuf, digest->hashbuf_size);
+	Sha1Finalise(&context, (SHA1_HASH *)digest->digest);
+	free(digest->hashbuf);
+	digest->hashbuf = NULL;
+	return;
+}
+
+/**
+ * digest_add_specfile - Add a specfile to the hashbuf and if gen_hash true
+ *			 then generate the hash.
+ * @digest: pointer to the selabel_digest struct
+ * @fp: file pointer for fread(3) or NULL if not.
+ * @from_addr: pointer at start of buffer for memcpy or NULL if not (used for
+ *	       mmap(3) files).
+ * @buf_len: length of buffer to copy.
+ * @path: pointer to the specfile.
+ *
+ * Return %0 on success, -%1 with @errno set on failure.
+ */
+int hidden digest_add_specfile(struct selabel_digest *digest, FILE *fp,
+				    char *from_addr, size_t buf_len,
+				    const char *path)
+{
+	unsigned char *tmp_buf;
+
+	/* If SELABEL_OPT_DIGEST not set then just return */
+	if (!digest)
+		return 0;
+
+	if (digest->hashbuf_size + buf_len < digest->hashbuf_size) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+	digest->hashbuf_size += buf_len;
+
+	tmp_buf = realloc(digest->hashbuf, digest->hashbuf_size);
+	if (!tmp_buf)
+		return -1;
+
+	digest->hashbuf = tmp_buf;
+
+	if (fp) {
+		rewind(fp);
+		if (fread(digest->hashbuf + (digest->hashbuf_size - buf_len),
+					    1, buf_len, fp) != buf_len)
+			return -1;
+
+		rewind(fp);
+	} else if (from_addr) {
+		tmp_buf = memcpy(digest->hashbuf +
+				    (digest->hashbuf_size - buf_len),
+				    from_addr, buf_len);
+		if (!tmp_buf)
+			return -1;
+	}
+	/* Now add path to list */
+	digest->specfile_list[digest->specfile_cnt] = strdup(path);
+	if (!digest->specfile_list[digest->specfile_cnt])
+		return -1;
+
+	digest->specfile_cnt++;
+	if (digest->specfile_cnt > DIGEST_FILES_MAX) {
+		errno = EOVERFLOW;
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/libselinux/src/label_x.c b/libselinux/src/label_x.c
index 8435b76..700def1 100644
--- a/libselinux/src/label_x.c
+++ b/libselinux/src/label_x.c
@@ -94,7 +94,7 @@
 	return 0;
 }
 
-static int init(struct selabel_handle *rec, struct selinux_opt *opts,
+static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
 		unsigned n)
 {
 	FILE *fp;
@@ -163,7 +163,12 @@
 	}
 	free(line_buf);
 
-	status = 0;
+	status = digest_add_specfile(rec->digest, fp, NULL, sb.st_size, path);
+	if (status)
+		goto finish;
+
+	digest_gen_hash(rec->digest);
+
 finish:
 	fclose(fp);
 	return status;
@@ -188,7 +193,7 @@
 	if (spec_arr)
 	    free(spec_arr);
 
-	memset(data, 0, sizeof(*data));
+	free(data);
 }
 
 static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
@@ -227,7 +232,7 @@
 		  data->nspec, total);
 }
 
-int selabel_x_init(struct selabel_handle *rec, struct selinux_opt *opts,
+int selabel_x_init(struct selabel_handle *rec, const struct selinux_opt *opts,
 		   unsigned nopts)
 {
 	struct saved_data *data;
diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c
index f990350..527a0a5 100644
--- a/libselinux/src/procattr.c
+++ b/libselinux/src/procattr.c
@@ -11,8 +11,6 @@
 
 #define UNSET (char *) -1
 
-static __thread pid_t cpid;
-static __thread pid_t tid;
 static __thread char *prev_current = UNSET;
 static __thread char * prev_exec = UNSET;
 static __thread char * prev_fscreate = UNSET;
@@ -24,15 +22,6 @@
 static int destructor_key_initialized = 0;
 static __thread char destructor_initialized;
 
-extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
-extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
-
-static int __selinux_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
-{
-  return __register_atfork (prepare, parent, child,
-                            &__dso_handle == NULL ? NULL : __dso_handle);
-}
-
 static pid_t gettid(void)
 {
 	return syscall(__NR_gettid);
@@ -52,14 +41,6 @@
 		free(prev_sockcreate);
 }
 
-static void free_procattr(void)
-{
-	procattr_thread_destructor(NULL);
-	tid = 0;
-	cpid = getpid();
-	prev_current = prev_exec = prev_fscreate = prev_keycreate = prev_sockcreate = UNSET;
-}
-
 void __attribute__((destructor)) procattr_destructor(void);
 
 void hidden __attribute__((destructor)) procattr_destructor(void)
@@ -79,7 +60,6 @@
 static void init_procattr(void)
 {
 	if (__selinux_key_create(&destructor_key, procattr_thread_destructor) == 0) {
-		__selinux_atfork(NULL, NULL, free_procattr);
 		destructor_key_initialized = 1;
 	}
 }
@@ -88,21 +68,26 @@
 {
 	int fd, rc;
 	char *path;
-
-	if (cpid != getpid())
-		free_procattr();
+	pid_t tid;
 
 	if (pid > 0)
 		rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr);
 	else {
-		if (!tid)
-			tid = gettid();
+		rc = asprintf(&path, "/proc/thread-self/attr/%s", attr);
+		if (rc < 0)
+			return -1;
+		fd = open(path, flags | O_CLOEXEC);
+		if (fd >= 0 || errno != ENOENT)
+			goto out;
+		free(path);
+		tid = gettid();
 		rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
 	}
 	if (rc < 0)
 		return -1;
 
 	fd = open(path, flags | O_CLOEXEC);
+out:
 	free(path);
 	return fd;
 }
@@ -120,9 +105,6 @@
 	__selinux_once(once, init_procattr);
 	init_thread_destructor();
 
-	if (cpid != getpid())
-		free_procattr();
-
 	switch (attr[0]) {
 		case 'c':
 			prev_context = prev_current;
@@ -220,9 +202,6 @@
 	__selinux_once(once, init_procattr);
 	init_thread_destructor();
 
-	if (cpid != getpid())
-		free_procattr();
-
 	switch (attr[0]) {
 		case 'c':
 			prev_context = &prev_current;
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
index 844e408..46566f6 100644
--- a/libselinux/src/selinux_internal.h
+++ b/libselinux/src/selinux_internal.h
@@ -102,6 +102,8 @@
 hidden_proto(security_get_initial_context_raw);
 hidden_proto(selinux_reset_config);
 
+hidden void flush_class_cache(void);
+
 extern int load_setlocaldefs hidden;
 extern int require_seusers hidden;
 extern int selinux_page_size hidden;
diff --git a/libselinux/src/selinuxswig_python.i b/libselinux/src/selinuxswig_python.i
index c9a2341..8cea18d 100644
--- a/libselinux/src/selinuxswig_python.i
+++ b/libselinux/src/selinuxswig_python.i
@@ -8,7 +8,7 @@
 
 %pythoncode %{
 
-import shutil, os, stat
+import shutil, os, errno, stat
 
 DISABLED = -1
 PERMISSIVE = 0
@@ -26,7 +26,12 @@
         status, context = matchpathcon(path, mode)
 
     if status == 0:
-        status, oldcontext = lgetfilecon(path)
+        try:
+            status, oldcontext = lgetfilecon(path)
+        except OSError as e:
+            if e.errno != errno.ENODATA:
+                raise
+            oldcontext = None
         if context != oldcontext:
             lsetfilecon(path, context)
 
diff --git a/libselinux/src/sha1.c b/libselinux/src/sha1.c
new file mode 100644
index 0000000..5f02af8
--- /dev/null
+++ b/libselinux/src/sha1.c
@@ -0,0 +1,214 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  LibSha1
+//
+//  Implementation of SHA1 hash function.
+//  Original author:  Steve Reid <sreid@sea-to-sky.net>
+//  Contributions by: James H. Brown <jbrown@burgoyne.com>, Saul Kravitz <Saul.Kravitz@celera.com>,
+//  and Ralph Giles <giles@ghostscript.com>
+//  Modified by WaterJuice retaining Public Domain license.
+//
+//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
+//  Modified to stop symbols being exported for libselinux shared library - October 2015
+//								       Richard Haines <richard_c_haines@btinternet.com>
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  IMPORTS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "sha1.h"
+#include "dso.h"
+#include <memory.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  TYPES
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef union
+{
+    uint8_t     c [64];
+    uint32_t    l [16];
+} CHAR64LONG16;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  INTERNAL FUNCTIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+// blk0() and blk() perform the initial expand.
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+// (R0+R1), R2, R3, R4 are the different operations used in SHA1
+#define R0(v,w,x,y,z,i)  z += ((w&(x^y))^y)     + blk0(i)+ 0x5A827999 + rol(v,5); w=rol(w,30);
+#define R1(v,w,x,y,z,i)  z += ((w&(x^y))^y)     + blk(i) + 0x5A827999 + rol(v,5); w=rol(w,30);
+#define R2(v,w,x,y,z,i)  z += (w^x^y)           + blk(i) + 0x6ED9EBA1 + rol(v,5); w=rol(w,30);
+#define R3(v,w,x,y,z,i)  z += (((w|x)&y)|(w&x)) + blk(i) + 0x8F1BBCDC + rol(v,5); w=rol(w,30);
+#define R4(v,w,x,y,z,i)  z += (w^x^y)           + blk(i) + 0xCA62C1D6 + rol(v,5); w=rol(w,30);
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  TransformFunction
+//
+//  Hash a single 512-bit block. This is the core of the algorithm
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static
+void
+    TransformFunction
+    (
+        uint32_t            state[5],
+        const uint8_t       buffer[64]
+    )
+{
+    uint32_t            a;
+    uint32_t            b;
+    uint32_t            c;
+    uint32_t            d;
+    uint32_t            e;
+    uint8_t             workspace[64];
+    CHAR64LONG16*       block = (CHAR64LONG16*) workspace;
+
+    memcpy( block, buffer, 64 );
+
+    // Copy context->state[] to working vars
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+
+    // 4 rounds of 20 operations each. Loop unrolled.
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
+    // Add the working vars back into context.state[]
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  PUBLIC FUNCTIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  Sha1Initialise
+//
+//  Initialises an SHA1 Context. Use this to initialise/reset a context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void hidden
+    Sha1Initialise
+    (
+        Sha1Context*                Context
+    )
+{
+    // SHA1 initialization constants
+    Context->State[0] = 0x67452301;
+    Context->State[1] = 0xEFCDAB89;
+    Context->State[2] = 0x98BADCFE;
+    Context->State[3] = 0x10325476;
+    Context->State[4] = 0xC3D2E1F0;
+    Context->Count[0] = 0;
+    Context->Count[1] = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  Sha1Update
+//
+//  Adds data to the SHA1 context. This will process the data and update the internal state of the context. Keep on
+//  calling this function until all the data has been added. Then call Sha1Finalise to calculate the hash.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void hidden
+    Sha1Update
+    (
+        Sha1Context*        Context,
+        void*               Buffer,
+        uint32_t            BufferSize
+    )
+{
+    uint32_t    i;
+    uint32_t    j;
+
+    j = (Context->Count[0] >> 3) & 63;
+    if( (Context->Count[0] += BufferSize << 3) < (BufferSize << 3) )
+    {
+        Context->Count[1]++;
+    }
+
+    Context->Count[1] += (BufferSize >> 29);
+    if( (j + BufferSize) > 63 )
+    {
+        i = 64 - j;
+        memcpy( &Context->Buffer[j], Buffer, i );
+        TransformFunction(Context->State, Context->Buffer);
+        for( ; i + 63 < BufferSize; i += 64 )
+        {
+            TransformFunction(Context->State, (uint8_t*)Buffer + i);
+        }
+        j = 0;
+    }
+    else
+    {
+        i = 0;
+    }
+
+    memcpy( &Context->Buffer[j], &((uint8_t*)Buffer)[i], BufferSize - i );
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  Sha1Finalise
+//
+//  Performs the final calculation of the hash and returns the digest (20 byte buffer containing 160bit hash). After
+//  calling this, Sha1Initialised must be used to reuse the context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void hidden
+    Sha1Finalise
+    (
+        Sha1Context*                Context,
+        SHA1_HASH*                  Digest
+    )
+{
+    uint32_t    i;
+    uint8_t     finalcount[8];
+
+    for( i=0; i<8; i++ )
+    {
+        finalcount[i] = (unsigned char)((Context->Count[(i >= 4 ? 0 : 1)]
+         >> ((3-(i & 3)) * 8) ) & 255);  // Endian independent
+    }
+    Sha1Update( Context, (uint8_t*)"\x80", 1 );
+    while( (Context->Count[0] & 504) != 448 )
+    {
+        Sha1Update( Context, (uint8_t*)"\0", 1 );
+    }
+
+    Sha1Update( Context, finalcount, 8 );  // Should cause a Sha1TransformFunction()
+    for( i=0; i<SHA1_HASH_SIZE; i++ )
+    {
+        Digest->bytes[i] = (uint8_t)((Context->State[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+}
diff --git a/libselinux/src/sha1.h b/libselinux/src/sha1.h
new file mode 100644
index 0000000..eac3c19
--- /dev/null
+++ b/libselinux/src/sha1.h
@@ -0,0 +1,85 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  LibSha1
+//
+//  Implementation of SHA1 hash function.
+//  Original author:  Steve Reid <sreid@sea-to-sky.net>
+//  Contributions by: James H. Brown <jbrown@burgoyne.com>, Saul Kravitz <Saul.Kravitz@celera.com>,
+//  and Ralph Giles <giles@ghostscript.com>
+//  Modified by WaterJuice retaining Public Domain license.
+//
+//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _sha1_h_
+#define _sha1_h_
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  IMPORTS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdint.h>
+#include <stdio.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  TYPES
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Sha1Context - This must be initialised using Sha1Initialised. Do not modify the contents of this structure directly.
+typedef struct
+{
+    uint32_t        State[5];
+    uint32_t        Count[2];
+    uint8_t         Buffer[64];
+} Sha1Context;
+
+#define SHA1_HASH_SIZE           ( 160 / 8 )
+
+typedef struct
+{
+    uint8_t      bytes [SHA1_HASH_SIZE];
+} SHA1_HASH;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  PUBLIC FUNCTIONS
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  Sha1Initialise
+//
+//  Initialises an SHA1 Context. Use this to initialise/reset a context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+    Sha1Initialise
+    (
+        Sha1Context*                Context
+    );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  Sha1Update
+//
+//  Adds data to the SHA1 context. This will process the data and update the internal state of the context. Keep on
+//  calling this function until all the data has been added. Then call Sha1Finalise to calculate the hash.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+    Sha1Update
+    (
+        Sha1Context*        Context,
+        void*               Buffer,
+        uint32_t            BufferSize
+    );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//  Sha1Finalise
+//
+//  Performs the final calculation of the hash and returns the digest (20 byte buffer containing 160bit hash). After
+//  calling this, Sha1Initialised must be used to reuse the context.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+    Sha1Finalise
+    (
+        Sha1Context*                Context,
+        SHA1_HASH*                  Digest
+    );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#endif //_sha1_h_
diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c
index 9ae8248..2dbec2b 100644
--- a/libselinux/src/stringrep.c
+++ b/libselinux/src/stringrep.c
@@ -158,6 +158,28 @@
 	return NULL;
 }
 
+hidden void flush_class_cache(void)
+{
+	struct discover_class_node *cur = discover_class_cache, *prev = NULL;
+	size_t i;
+
+	while (cur != NULL) {
+		free(cur->name);
+
+		for (i = 0; i < MAXVECTORS; i++)
+			free(cur->perms[i]);
+
+		free(cur->perms);
+
+		prev = cur;
+		cur = cur->next;
+
+		free(prev);
+	}
+
+	discover_class_cache = NULL;
+}
+
 security_class_t string_to_security_class(const char *s)
 {
 	struct discover_class_node *node;
diff --git a/libselinux/utils/Makefile b/libselinux/utils/Makefile
index 5499538..cac85c7 100644
--- a/libselinux/utils/Makefile
+++ b/libselinux/utils/Makefile
@@ -28,7 +28,7 @@
 
 TARGETS=$(patsubst %.c,%,$(wildcard *.c))
 
-sefcontext_compile: LDLIBS += -lpcre
+sefcontext_compile: LDLIBS += -lpcre ../src/libselinux.a -lsepol
 
 ifeq ($(DISABLE_AVC),y)
 	UNUSED_TARGETS+=compute_av compute_create compute_member compute_relabel
diff --git a/libselinux/utils/sefcontext_compile.c b/libselinux/utils/sefcontext_compile.c
index 03bc0a7..d2578b6 100644
--- a/libselinux/utils/sefcontext_compile.c
+++ b/libselinux/utils/sefcontext_compile.c
@@ -7,117 +7,62 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-
-#include <linux/limits.h>
+#include <getopt.h>
+#include <limits.h>
+#include <selinux/selinux.h>
+#include <sepol/sepol.h>
 
 #include "../src/label_file.h"
 
-static int process_file(struct saved_data *data, const char *filename)
+const char *policy_file;
+static int ctx_err;
+
+static int validate_context(char **ctxp)
 {
-	struct spec *spec;
+	char *ctx = *ctxp;
+
+	if (policy_file && sepol_check_context(ctx) < 0) {
+		ctx_err = -1;
+		return ctx_err;
+	}
+
+	return 0;
+}
+
+static int process_file(struct selabel_handle *rec, const char *filename)
+{
 	unsigned int line_num;
+	int rc;
 	char *line_buf = NULL;
-	size_t line_len;
-	ssize_t len;
+	size_t line_len = 0;
 	FILE *context_file;
+	const char *prefix = NULL;
 
 	context_file = fopen(filename, "r");
 	if (!context_file) {
-		fprintf(stderr, "Error opening %s: %s\n", filename, strerror(errno));
+		fprintf(stderr, "Error opening %s: %s\n",
+			    filename, strerror(errno));
 		return -1;
 	}
 
 	line_num = 0;
-	while ((len = getline(&line_buf, &line_len, context_file)) != -1) {
-		char *context = NULL;
-		char *mode = NULL;
-		char *regex = NULL;
-		char *cp, *anchored_regex;
-		pcre *re;
-		pcre_extra *sd;
-		const char *err;
-		int items, erroff, rc;
-		size_t regex_len;
-		int32_t stem_id;
-
-		line_num++;
-
-		items = read_spec_entries(line_buf, 3, &regex, &mode, &context);
-		if (items < 0)
-			return -1;
-
-		if (items == 0)
-			continue;
-		else if (items == 1) {
-			fprintf(stderr,
-				 "line: %u has invalid entry - skipping: %s\n",
-				 line_num, line_buf);
-			continue;
-		} else if (items == 2) {
-			context = mode;
-			mode = NULL;
+	rc = 0;
+	while (getline(&line_buf, &line_len, context_file) > 0) {
+		rc = process_line(rec, filename, prefix, line_buf, ++line_num);
+		if (rc || ctx_err) {
+			/* With -p option need to check and fail if ctx err as
+			 * process_line() context validation on Linux does not
+			 * return an error, but does print the error line to
+			 * stderr. Android will set both to error and print
+			 * the error line. */
+			rc = -1;
+			goto out;
 		}
-
-		rc = grow_specs(data);
-		if (rc) {
-			fprintf(stderr, "grow_specs failed: %s\n", strerror(errno));
-			return rc;
-		}
-
-		spec = &data->spec_arr[data->nspec];
-
-		spec->lr.ctx_raw = context;
-		spec->mode = string_to_mode(mode);
-		if (spec->mode == (mode_t)-1) {
-			fprintf(stderr, "%s: line %u has invalid file type %s\n",
-				regex, line_num + 1, mode);
-			spec->mode = 0;
-		}
-		free(mode);
-		spec->regex_str = regex;
-
-		stem_id = find_stem_from_spec(data, regex);
-		spec->stem_id = stem_id;
-		/* skip past the fixed stem part */
-		if (stem_id != -1)
-			regex += data->stem_arr[stem_id].len;
-
-		regex_len = strlen(regex);
-		cp = anchored_regex = malloc(regex_len + 3);
-		if (!cp) {
-			fprintf(stderr, "Malloc Failed: %s\n", strerror(errno));
-			return -1;
-		}
-		*cp++ = '^';
-		memcpy(cp, regex, regex_len);
-		cp += regex_len;
-		*cp++ = '$';
-		*cp = '\0';
-
-		spec_hasMetaChars(spec);
-
-		re = pcre_compile(anchored_regex, PCRE_DOTALL, &err, &erroff, NULL);
-		if (!re) {
-			fprintf(stderr, "PCRE compilation failed for %s at offset %d: %s\n", anchored_regex, erroff, err);
-			return -1;
-		}
-		spec->regex = re;
-
-		sd = pcre_study(re, 0, &err);
-		if (!sd) {
-			fprintf(stderr, "PCRE study failed for %s: %s\n", anchored_regex, err);
-			return -1;
-		}
-		free(anchored_regex);
-		spec->sd = sd;
-
-		data->nspec++;
 	}
-
+out:
 	free(line_buf);
 	fclose(context_file);
-
-	return 0;
+	return rc;
 }
 
 /*
@@ -129,18 +74,19 @@
  * char - pcre version string EXCLUDING nul
  * u32 - number of stems
  * ** Stems
- * 	u32  - length of stem EXCLUDING nul
- * 	char - stem char array INCLUDING nul
+ *	u32  - length of stem EXCLUDING nul
+ *	char - stem char array INCLUDING nul
  * u32 - number of regexs
  * ** Regexes
- * 	u32  - length of upcoming context INCLUDING nul
- * 	char - char array of the raw context
+ *	u32  - length of upcoming context INCLUDING nul
+ *	char - char array of the raw context
  *	u32  - length of the upcoming regex_str
  *	char - char array of the original regex string including the stem.
  *	u32  - mode bits for >= SELINUX_COMPILED_FCONTEXT_MODE
  *	       mode_t for <= SELINUX_COMPILED_FCONTEXT_PCRE_VERS
  *	s32  - stemid associated with the regex
  *	u32  - spec has meta characters
+ *	u32  - The specs prefix_len if >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN
  *	u32  - data length of the pcre regex
  *	char - a bufer holding the raw pcre regex info
  *	u32  - data length of the pcre regex study daya
@@ -214,6 +160,7 @@
 		char *context = specs[i].lr.ctx_raw;
 		char *regex_str = specs[i].regex_str;
 		mode_t mode = specs[i].mode;
+		size_t prefix_len = specs[i].prefix_len;
 		int32_t stem_id = specs[i].stem_id;
 		pcre *re = specs[i].regex;
 		pcre_extra *sd = get_pcre_extra(&specs[i]);
@@ -259,6 +206,12 @@
 		if (len != 1)
 			goto err;
 
+		/* For SELINUX_COMPILED_FCONTEXT_PREFIX_LEN */
+		to_write = prefix_len;
+		len = fwrite(&to_write, sizeof(to_write), 1, bin_file);
+		if (len != 1)
+			goto err;
+
 		/* determine the size of the pcre data in bytes */
 		rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size);
 		if (rc < 0)
@@ -301,7 +254,7 @@
 	goto out;
 }
 
-static int free_specs(struct saved_data *data)
+static void free_specs(struct saved_data *data)
 {
 	struct spec *specs = data->spec_arr;
 	unsigned int num_entries = data->nspec;
@@ -311,59 +264,144 @@
 		free(specs[i].lr.ctx_raw);
 		free(specs[i].lr.ctx_trans);
 		free(specs[i].regex_str);
+		free(specs[i].type_str);
 		pcre_free(specs[i].regex);
 		pcre_free_study(specs[i].sd);
 	}
 	free(specs);
 
 	num_entries = data->num_stems;
-	for (i = 0; i < num_entries; i++) {
+	for (i = 0; i < num_entries; i++)
 		free(data->stem_arr[i].buf);
-	}
 	free(data->stem_arr);
 
 	memset(data, 0, sizeof(*data));
-	return 0;
+}
+
+static void usage(const char *progname)
+{
+	fprintf(stderr,
+	    "usage: %s [-o out_file] [-p policy_file] fc_file\n"
+	    "Where:\n\t"
+	    "-o       Optional file name of the PCRE formatted binary\n\t"
+	    "         file to be output. If not specified the default\n\t"
+	    "         will be fc_file with the .bin suffix appended.\n\t"
+	    "-p       Optional binary policy file that will be used to\n\t"
+	    "         validate contexts defined in the fc_file.\n\t"
+	    "fc_file  The text based file contexts file to be processed.\n",
+	    progname);
+		exit(EXIT_FAILURE);
 }
 
 int main(int argc, char *argv[])
 {
-	struct saved_data data;
-	const char *path;
+	const char *path = NULL;
+	const char *out_file = NULL;
 	char stack_path[PATH_MAX + 1];
-	int rc;
-	char *tmp= NULL;
-	int fd;
+	char *tmp = NULL;
+	int fd, rc, opt;
+	FILE *policy_fp = NULL;
 	struct stat buf;
+	struct selabel_handle *rec = NULL;
+	struct saved_data *data = NULL;
 
-	if (argc != 2) {
-		fprintf(stderr, "usage: %s input_file\n", argv[0]);
-		exit(EXIT_FAILURE);
+	if (argc < 2)
+		usage(argv[0]);
+
+	while ((opt = getopt(argc, argv, "o:p:")) > 0) {
+		switch (opt) {
+		case 'o':
+			out_file = optarg;
+			break;
+		case 'p':
+			policy_file = optarg;
+			break;
+		default:
+			usage(argv[0]);
+		}
 	}
 
-	memset(&data, 0, sizeof(data));
+	if (optind >= argc)
+		usage(argv[0]);
 
-	path = argv[1];
-
+	path = argv[optind];
 	if (stat(path, &buf) < 0) {
 		fprintf(stderr, "Can not stat: %s: %m\n", path);
 		exit(EXIT_FAILURE);
 	}
 
-	rc = process_file(&data, path);
+	/* Open binary policy if supplied. */
+	if (policy_file) {
+		policy_fp = fopen(policy_file, "r");
+
+		if (!policy_fp) {
+			fprintf(stderr, "Failed to open policy: %s\n",
+							    policy_file);
+			exit(EXIT_FAILURE);
+		}
+
+		if (sepol_set_policydb_from_file(policy_fp) < 0) {
+			fprintf(stderr, "Failed to load policy: %s\n",
+							    policy_file);
+			fclose(policy_fp);
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	/* Generate dummy handle for process_line() function */
+	rec = (struct selabel_handle *)calloc(1, sizeof(*rec));
+	if (!rec) {
+		fprintf(stderr, "Failed to calloc handle\n");
+		if (policy_fp)
+			fclose(policy_fp);
+		exit(EXIT_FAILURE);
+	}
+	rec->backend = SELABEL_CTX_FILE;
+
+	/* Need to set validation on to get the bin file generated by the
+	 * process_line function, however as the bin file being generated
+	 * may not be related to the currently loaded policy (that it
+	 * would be validated against), then set callback to ignore any
+	 * validation - unless the -p option is used in which case if an
+	 * error is detected, the process will be aborted. */
+	rec->validating = 1;
+	selinux_set_callback(SELINUX_CB_VALIDATE,
+			    (union selinux_callback)&validate_context);
+
+	data = (struct saved_data *)calloc(1, sizeof(*data));
+	if (!data) {
+		fprintf(stderr, "Failed to calloc saved_data\n");
+		free(rec);
+		if (policy_fp)
+			fclose(policy_fp);
+		exit(EXIT_FAILURE);
+	}
+
+	rec->data = data;
+
+	rc = process_file(rec, path);
 	if (rc < 0)
-		return rc;
+		goto err;
 
-	rc = sort_specs(&data);
+	rc = sort_specs(data);
 	if (rc)
-		return rc;
+		goto err;
 
-	rc = snprintf(stack_path, sizeof(stack_path), "%s.bin", path);
+	if (out_file)
+		rc = snprintf(stack_path, sizeof(stack_path), "%s", out_file);
+	else
+		rc = snprintf(stack_path, sizeof(stack_path), "%s.bin", path);
+
 	if (rc < 0 || rc >= (int)sizeof(stack_path))
-		return rc;
+		goto err;
 
-	if (asprintf(&tmp, "%sXXXXXX", stack_path) < 0)
-		return -1;
+	tmp = malloc(strlen(stack_path) + 7);
+	if (!tmp)
+		goto err;
+
+	rc = sprintf(tmp, "%sXXXXXX", stack_path);
+	if (rc < 0)
+		goto err;
 
 	fd  = mkstemp(tmp);
 	if (fd < 0)
@@ -372,23 +410,30 @@
 	rc = fchmod(fd, buf.st_mode);
 	if (rc < 0) {
 		perror("fchmod failed to set permission on compiled regexs");
-		goto err;
+		goto err_unlink;
 	}
 
-	rc = write_binary_file(&data, fd);
-
+	rc = write_binary_file(data, fd);
 	if (rc < 0)
-		goto err;
+		goto err_unlink;
 
-	rename(tmp, stack_path);
-	rc = free_specs(&data);
+	rc = rename(tmp, stack_path);
 	if (rc < 0)
-		goto err;
+		goto err_unlink;
 
 	rc = 0;
 out:
+	if (policy_fp)
+		fclose(policy_fp);
+
+	free_specs(data);
+	free(rec);
+	free(data);
 	free(tmp);
 	return rc;
+
+err_unlink:
+	unlink(tmp);
 err:
 	rc = -1;
 	goto out;
diff --git a/libselinux/utils/selabel_digest.c b/libselinux/utils/selabel_digest.c
new file mode 100644
index 0000000..1e9fb34
--- /dev/null
+++ b/libselinux/utils/selabel_digest.c
@@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+
+static size_t digest_len;
+
+static void usage(const char *progname)
+{
+	fprintf(stderr,
+		"usage: %s -b backend [-d] [-v] [-B] [-i] [-f file]\n\n"
+		"Where:\n\t"
+		"-b  The backend - \"file\", \"media\", \"x\", \"db\" or "
+			"\"prop\"\n\t"
+		"-v  Run \"cat <specfile_list> | openssl dgst -sha1 -hex\"\n\t"
+		"    on the list of specfiles to compare the SHA1 digests.\n\t"
+		"-B  Use base specfiles only (valid for \"-b file\" only).\n\t"
+		"-i  Do not request a digest.\n\t"
+		"-f  Optional file containing the specs (defaults to\n\t"
+		"    those used by loaded policy).\n\n",
+		progname);
+	exit(1);
+}
+
+static int run_check_digest(char *cmd, char *selabel_digest)
+{
+	FILE *fp;
+	char files_digest[128];
+	char *files_ptr;
+	int rc = 0;
+
+	fp = popen(cmd, "r");
+	if (!fp) {
+		printf("Failed to run command line\n");
+		return -1;
+	}
+
+	/* Only expect one line "(stdin)= x.." so read and find first space */
+	while (fgets(files_digest, sizeof(files_digest) - 1, fp) != NULL)
+		;
+
+	files_ptr = strstr(files_digest, " ");
+
+	rc = strncmp(selabel_digest, files_ptr + 1, digest_len * 2);
+	if (rc) {
+		printf("Failed validation:\n\tselabel_digest: %s\n\t"
+				    "files_digest:   %s\n",
+				    selabel_digest, files_ptr + 1);
+	} else {
+		printf("Passed validation - digest: %s\n", selabel_digest);
+	}
+
+	pclose(fp);
+	return rc;
+}
+
+int main(int argc, char **argv)
+{
+	int backend = 0, rc, opt, i, validate = 0;
+	char *baseonly = NULL, *file = NULL, *digest = (char *)1;
+	char **specfiles = NULL;
+	unsigned char *sha1_digest = NULL;
+	size_t num_specfiles;
+
+	char cmd_buf[4096];
+	char *cmd_ptr;
+	char *sha1_buf;
+
+	struct selabel_handle *hnd;
+	struct selinux_opt selabel_option[] = {
+		{ SELABEL_OPT_PATH, file },
+		{ SELABEL_OPT_BASEONLY, baseonly },
+		{ SELABEL_OPT_DIGEST, digest }
+	};
+
+	if (argc < 3)
+		usage(argv[0]);
+
+	while ((opt = getopt(argc, argv, "ib:Bvf:")) > 0) {
+		switch (opt) {
+		case 'b':
+			if (!strcasecmp(optarg, "file")) {
+				backend = SELABEL_CTX_FILE;
+			} else if (!strcmp(optarg, "media")) {
+				backend = SELABEL_CTX_MEDIA;
+			} else if (!strcmp(optarg, "x")) {
+				backend = SELABEL_CTX_X;
+			} else if (!strcmp(optarg, "db")) {
+				backend = SELABEL_CTX_DB;
+			} else if (!strcmp(optarg, "prop")) {
+				backend = SELABEL_CTX_ANDROID_PROP;
+			} else {
+				fprintf(stderr, "Unknown backend: %s\n",
+								    optarg);
+				usage(argv[0]);
+			}
+			break;
+		case 'B':
+			baseonly = (char *)1;
+			break;
+		case 'v':
+			validate = 1;
+			break;
+		case 'i':
+			digest = NULL;
+			break;
+		case 'f':
+			file = optarg;
+			break;
+		default:
+			usage(argv[0]);
+		}
+	}
+
+	memset(cmd_buf, 0, sizeof(cmd_buf));
+
+	selabel_option[0].value = file;
+	selabel_option[1].value = baseonly;
+	selabel_option[2].value = digest;
+
+	hnd = selabel_open(backend, selabel_option, 3);
+	if (!hnd) {
+		switch (errno) {
+		case EOVERFLOW:
+			fprintf(stderr, "ERROR Number of specfiles or specfile"
+					" buffer caused an overflow.\n");
+			break;
+		default:
+			fprintf(stderr, "ERROR: selabel_open: %s\n",
+						    strerror(errno));
+		}
+		return -1;
+	}
+
+	rc = selabel_digest(hnd, &sha1_digest, &digest_len, &specfiles,
+							    &num_specfiles);
+
+	if (rc) {
+		switch (errno) {
+		case EINVAL:
+			fprintf(stderr, "No digest available.\n");
+			break;
+		default:
+			fprintf(stderr, "selabel_digest ERROR: %s\n",
+						    strerror(errno));
+		}
+		goto err;
+	}
+
+	sha1_buf = malloc(digest_len * 2 + 1);
+	if (!sha1_buf) {
+		fprintf(stderr, "Could not malloc buffer ERROR: %s\n",
+						    strerror(errno));
+		rc = -1;
+		goto err;
+	}
+
+	printf("SHA1 digest: ");
+	for (i = 0; i < digest_len; i++)
+		sprintf(&(sha1_buf[i * 2]), "%02x", sha1_digest[i]);
+
+	printf("%s\n", sha1_buf);
+	printf("calculated using the following specfile(s):\n");
+
+	if (specfiles) {
+		cmd_ptr = &cmd_buf[0];
+		sprintf(cmd_ptr, "/usr/bin/cat ");
+		cmd_ptr = &cmd_buf[0] + strlen(cmd_buf);
+
+		for (i = 0; i < num_specfiles; i++) {
+			sprintf(cmd_ptr, "%s ", specfiles[i]);
+			cmd_ptr += strlen(specfiles[i]) + 1;
+			printf("%s\n", specfiles[i]);
+		}
+		sprintf(cmd_ptr, "| /usr/bin/openssl dgst -sha1 -hex");
+
+		if (validate)
+			rc = run_check_digest(cmd_buf, sha1_buf);
+	}
+
+	free(sha1_buf);
+err:
+	selabel_close(hnd);
+	return rc;
+}
diff --git a/libsemanage/ChangeLog b/libsemanage/ChangeLog
index 217c3e7..b55a028 100644
--- a/libsemanage/ChangeLog
+++ b/libsemanage/ChangeLog
@@ -1,3 +1,12 @@
+	* semanage_migrate_store: Load libsepol.so.1 instead of libsepol.so, from Laurent Bigonville.
+	* Store homedir_template and users_extra in policy store, from Steve Lawrence
+	* Fix null pointer dereference in semanage_module_key_destroy, from Yuli Khodorkovskiy.
+	* Add semanage_module_extract() to extract a module as CIL or HLL, from Yuli Khodorkovskiy.
+	* semanage_migrate_store: add -r <root> option for migrating inside chroots, from Petr Lautrbach.
+	* Add file_contexts and seusers to the store, from Yuli Khodorkovskiy.
+	* Add policy binary and file_contexts.local to the store, from Yuli Khodorkovskiy.
+	* Allow to install compressed modules without a compression extension,
+	  from Petr Lautrbach.
 	* Do not copy contexts in semanage_migrate_store, from Jason Zaman.
 	* Fix logic in bunzip for uncompressed pp files, from Thomas Hurd.
 	* Fix fname[] initialization in test_utilities.c, from Petr Lautrbach.
diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h
index 4267bd2..4b93e54 100644
--- a/libsemanage/include/semanage/modules.h
+++ b/libsemanage/include/semanage/modules.h
@@ -24,6 +24,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <semanage/handle.h>
+#include <sys/types.h>
 
 typedef struct semanage_module_key semanage_module_key_t;
 
@@ -41,6 +42,22 @@
    modules, only name at this time */
 typedef struct semanage_module_info semanage_module_info_t;
 
+/* Look up a module using @modkey. The module's raw data is returned as a
+ * @mapped_data blob and size of the mapped_data is returned as @data_len.
+ * @modinfo contains additional information which can be used by the caller such
+ * as the high level language extension of @mapped_data.
+ *
+ * On success, the caller is responsible for unmapping @mapped_data with munmap(),
+ * destroying @modinfo with semanage_module_info_destroy(), and freeing @modinfo.
+ *
+ * Returns 0 on success and -1 on error.
+ */
+int semanage_module_extract(semanage_handle_t *sh,
+				 semanage_module_key_t *modkey,
+				 int extract_cil,
+				 void **mapped_data,
+				 size_t *data_len,
+				 semanage_module_info_t **modinfo);
 int semanage_module_list(semanage_handle_t *,
 			 semanage_module_info_t **, int *num_modules);
 void semanage_module_info_datum_destroy(semanage_module_info_t *);
diff --git a/libsemanage/src/booleans_policydb.c b/libsemanage/src/booleans_policydb.c
index 74af2a3..6869d6c 100644
--- a/libsemanage/src/booleans_policydb.c
+++ b/libsemanage/src/booleans_policydb.c
@@ -55,10 +55,8 @@
 {
 
 	if (dbase_policydb_init(handle,
-				semanage_final_path(SEMANAGE_FINAL_SELINUX,
-						    SEMANAGE_KERNEL),
-				semanage_final_path(SEMANAGE_FINAL_TMP,
-						    SEMANAGE_KERNEL),
+				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
 				&SEMANAGE_BOOL_RTABLE,
 				&SEMANAGE_BOOL_POLICYDB_RTABLE,
 				&dconfig->dbase) < 0)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index e4f168e..68dd0d1 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -66,6 +66,12 @@
 static int semanage_direct_install(semanage_handle_t * sh, char *data,
 				   size_t data_len, const char *module_name, const char *lang_ext);
 static int semanage_direct_install_file(semanage_handle_t * sh, const char *module_name);
+static int semanage_direct_extract(semanage_handle_t * sh,
+					   semanage_module_key_t *modkey,
+					   int extract_cil,
+					   void **mapped_data,
+					   size_t *data_len,
+					   semanage_module_info_t **modinfo);
 static int semanage_direct_remove(semanage_handle_t * sh, char *module_name);
 static int semanage_direct_list(semanage_handle_t * sh,
 				semanage_module_info_t ** modinfo,
@@ -100,6 +106,7 @@
 	.begin_trans = semanage_direct_begintrans,
 	.commit = semanage_direct_commit,
 	.install = semanage_direct_install,
+	.extract = semanage_direct_extract,
 	.install_file = semanage_direct_install_file,
 	.remove = semanage_direct_remove,
 	.list = semanage_direct_list,
@@ -196,10 +203,8 @@
 		goto err;
 
 	if (fcontext_file_dbase_init(sh,
-				     semanage_final_path(SEMANAGE_FINAL_SELINUX,
-							 SEMANAGE_FC_LOCAL),
-				     semanage_final_path(SEMANAGE_FINAL_TMP,
-							 SEMANAGE_FC_LOCAL),
+				     semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_LOCAL),
+				     semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
 				     semanage_fcontext_dbase_local(sh)) < 0)
 		goto err;
 
@@ -250,18 +255,14 @@
 		goto err;
 
 	if (fcontext_file_dbase_init(sh,
-				     semanage_final_path(SEMANAGE_FINAL_SELINUX,
-							 SEMANAGE_FC),
-				     semanage_final_path(SEMANAGE_FINAL_TMP,
-							 SEMANAGE_FC),
+				     semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC),
+				     semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
 				     semanage_fcontext_dbase_policy(sh)) < 0)
 		goto err;
 
 	if (seuser_file_dbase_init(sh,
-				   semanage_final_path(SEMANAGE_FINAL_SELINUX,
-						       SEMANAGE_SEUSERS),
-				   semanage_final_path(SEMANAGE_FINAL_TMP,
-						       SEMANAGE_SEUSERS),
+				   semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_SEUSERS),
+				   semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
 				   semanage_seuser_dbase_policy(sh)) < 0)
 		goto err;
 
@@ -502,15 +503,32 @@
  * the file into '*data'.
  * Returns the total number of bytes in memory .
  * Returns -1 if file could not be opened or mapped. */
-static ssize_t map_file(semanage_handle_t *sh, int fd, char **data,
+static ssize_t map_file(semanage_handle_t *sh, const char *path, char **data,
 			int *compressed)
 {
 	ssize_t size = -1;
 	char *uncompress;
-	if ((size = bunzip(sh, fdopen(fd, "r"), &uncompress)) > 0) {
+	int fd = -1;
+	FILE *file = NULL;
+
+	fd = open(path, O_RDONLY);
+	if (fd == -1) {
+		ERR(sh, "Unable to open %s\n", path);
+		return -1;
+	}
+
+	file = fdopen(fd, "r");
+	if (file == NULL) {
+		ERR(sh, "Unable to open %s\n", path);
+		close(fd);
+		return -1;
+	}
+
+	if ((size = bunzip(sh, file, &uncompress)) > 0) {
 		*data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
 		if (*data == MAP_FAILED) {
 			free(uncompress);
+			fclose(file);
 			return -1;
 		} else {
 			memcpy(*data, uncompress, size);
@@ -529,6 +547,8 @@
 		*compressed = 0;
 	} 
 
+	fclose(file);
+
 	return size;
 }
 
@@ -604,7 +624,7 @@
 	}
 
 	if (size > 0) {
-		ofilename = semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS);
+		ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
 		if (ofilename == NULL) {
 			return -1;
 		}
@@ -892,9 +912,8 @@
 	return ret;
 }
 
-static int semanage_compile_hll(semanage_handle_t *sh,
-				semanage_module_info_t *modinfos,
-				int num_modinfos)
+static int semanage_compile_module(semanage_handle_t *sh,
+				semanage_module_info_t *modinfo)
 {
 	char cil_path[PATH_MAX];
 	char hll_path[PATH_MAX];
@@ -907,19 +926,108 @@
 	ssize_t hll_data_len = 0;
 	ssize_t bzip_status;
 	int status = 0;
-	int i, compressed;
-	int in_fd = -1;
+	int compressed;
 	size_t cil_data_len;
 	size_t err_data_len;
 
+	if (!strcasecmp(modinfo->lang_ext, "cil")) {
+		goto cleanup;
+	}
+
+	status = semanage_get_hll_compiler_path(sh, modinfo->lang_ext, &compiler_path);
+	if (status != 0) {
+		goto cleanup;
+	}
+
+	status = semanage_module_get_path(
+			sh,
+			modinfo,
+			SEMANAGE_MODULE_PATH_CIL,
+			cil_path,
+			sizeof(cil_path));
+	if (status != 0) {
+		goto cleanup;
+	}
+
+	status = semanage_module_get_path(
+			sh,
+			modinfo,
+			SEMANAGE_MODULE_PATH_HLL,
+			hll_path,
+			sizeof(hll_path));
+	if (status != 0) {
+		goto cleanup;
+	}
+
+	if ((hll_data_len = map_file(sh, hll_path, &hll_data, &compressed)) <= 0) {
+		ERR(sh, "Unable to read file %s\n", hll_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
+	if (err_data_len > 0) {
+		for (start = end = err_data; end < err_data + err_data_len; end++) {
+			if (*end == '\n') {
+				fprintf(stderr, "%s: ", modinfo->name);
+				fwrite(start, 1, end - start + 1, stderr);
+				start = end + 1;
+			}
+		}
+
+		if (end != start) {
+			fprintf(stderr, "%s: ", modinfo->name);
+			fwrite(start, 1, end - start, stderr);
+			fprintf(stderr, "\n");
+		}
+	}
+	if (status != 0) {
+		goto cleanup;
+	}
+
+	bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
+	if (bzip_status == -1) {
+		ERR(sh, "Failed to bzip %s\n", cil_path);
+		status = -1;
+		goto cleanup;
+	}
+
+	if (sh->conf->remove_hll == 1) {
+		status = unlink(hll_path);
+		if (status != 0) {
+			ERR(sh, "Error while removing HLL file %s: %s", hll_path, strerror(errno));
+			goto cleanup;
+		}
+
+		status = semanage_direct_write_langext(sh, "cil", modinfo);
+		if (status != 0) {
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	if (hll_data_len > 0) {
+		munmap(hll_data, hll_data_len);
+	}
+	free(cil_data);
+	free(err_data);
+	free(compiler_path);
+
+	return status;
+}
+
+static int semanage_compile_hll_modules(semanage_handle_t *sh,
+				semanage_module_info_t *modinfos,
+				int num_modinfos)
+{
+	int status = 0;
+	int i;
+	char cil_path[PATH_MAX];
+
 	assert(sh);
 	assert(modinfos);
 
 	for (i = 0; i < num_modinfos; i++) {
-		if (!strcasecmp(modinfos[i].lang_ext, "cil")) {
-			continue;
-		}
-
 		status = semanage_module_get_path(
 				sh,
 				&modinfos[i],
@@ -931,101 +1039,19 @@
 		}
 
 		if (semanage_get_ignore_module_cache(sh) == 0 &&
-			access(cil_path, F_OK) == 0) {
+				access(cil_path, F_OK) == 0) {
 			continue;
 		}
 
-		status = semanage_get_hll_compiler_path(sh, modinfos[i].lang_ext, &compiler_path);
-		if (status != 0) {
+		status = semanage_compile_module(sh, &modinfos[i]);
+		if (status < 0) {
 			goto cleanup;
 		}
-
-		status = semanage_module_get_path(
-				sh,
-				&modinfos[i],
-				SEMANAGE_MODULE_PATH_HLL,
-				hll_path,
-				sizeof(hll_path));
-		if (status != 0) {
-			goto cleanup;
-		}
-
-		if ((in_fd = open(hll_path, O_RDONLY)) == -1) {
-			ERR(sh, "Unable to open %s\n", hll_path);
-			status = -1;
-			goto cleanup;
-		}
-
-		if ((hll_data_len = map_file(sh, in_fd, &hll_data, &compressed)) <= 0) {
-			ERR(sh, "Unable to read file %s\n", hll_path);
-			status = -1;
-			goto cleanup;
-		}
-
-		if (in_fd >= 0) close(in_fd);
-		in_fd = -1;
-
-		status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
-		if (err_data_len > 0) {
-			for (start = end = err_data; end < err_data + err_data_len; end++) {
-				if (*end == '\n') {
-					fprintf(stderr, "%s: ", modinfos[i].name);
-					fwrite(start, 1, end - start + 1, stderr);
-					start = end + 1;
-				}
-			}
-
-			if (end != start) {
-				fprintf(stderr, "%s: ", modinfos[i].name);
-				fwrite(start, 1, end - start, stderr);
-				fprintf(stderr, "\n");
-			}
-		}
-		if (status != 0) {
-			goto cleanup;
-		}
-
-		if (sh->conf->remove_hll == 1) {
-			status = unlink(hll_path);
-			if (status != 0) {
-				ERR(sh, "Error while removing HLL file %s: %s", hll_path, strerror(errno));
-				goto cleanup;
-			}
-
-			status = semanage_direct_write_langext(sh, "cil", &modinfos[i]);
-			if (status != 0) {
-				goto cleanup;
-			}
-		}
-
-		bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
-		if (bzip_status == -1) {
-			ERR(sh, "Failed to bzip %s\n", cil_path);
-			status = -1;
-			goto cleanup;
-		}
-
-		if (hll_data_len > 0) munmap(hll_data, hll_data_len);
-		hll_data_len = 0;
-
-		free(cil_data);
-		free(err_data);
-		free(compiler_path);
-		cil_data = NULL;
-		err_data = NULL;
-		compiler_path = NULL;
-		cil_data_len = 0;
-		err_data_len = 0;
 	}
 
 	status = 0;
 
 cleanup:
-	if (hll_data_len > 0) munmap(hll_data, hll_data_len);
-	if (in_fd >= 0) close(in_fd);
-	free(cil_data);
-	free(err_data);
-	free(compiler_path);
 	return status;
 }
 
@@ -1041,7 +1067,8 @@
 	size_t fc_buffer_len = 0;
 	const char *ofilename = NULL;
 	const char *path;
-	int retval = -1, num_modinfos = 0, i;
+	int retval = -1, num_modinfos = 0, i, missing_policy_kern = 0,
+		missing_seusers = 0, missing_fc = 0, missing = 0;
 	sepol_policydb_t *out = NULL;
 	struct cil_db *cildb = NULL;
 	semanage_module_info_t *modinfos = NULL;
@@ -1143,8 +1170,36 @@
 	modified |= dontaudit_modified;
 	modified |= preserve_tunables_modified;
 
+	/* This is for systems that have already migrated with an older version
+	 * of semanage_migrate_store. The older version did not copy policy.kern so
+	 * the policy binary must be rebuilt here.
+	 */
+	if (!sh->do_rebuild && !modified) {
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL);
+
+		if (access(path, F_OK) != 0) {
+			missing_policy_kern = 1;
+		}
+
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC);
+
+		if (access(path, F_OK) != 0) {
+			missing_fc = 1;
+		}
+
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
+
+		if (access(path, F_OK) != 0) {
+			missing_seusers = 1;
+		}
+	}
+
+	missing |= missing_policy_kern;
+	missing |= missing_fc;
+	missing |= missing_seusers;
+
 	/* If there were policy changes, or explicitly requested, rebuild the policy */
-	if (sh->do_rebuild || modified) {
+	if (sh->do_rebuild || modified || missing) {
 		/* =================== Module expansion =============== */
 
 		retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos);
@@ -1156,7 +1211,7 @@
 			goto cleanup;
 		}
 
-		retval = semanage_compile_hll(sh, modinfos, num_modinfos);
+		retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos);
 		if (retval < 0) {
 			ERR(sh, "Failed to compile hll files into cil files.\n");
 			goto cleanup;
@@ -1217,6 +1272,9 @@
 		if (retval < 0)
 			goto cleanup;
 
+		/* remove FC_TMPL now that it is now longer needed */
+		unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL));
+
 		pfcontexts->dtable->drop_cache(pfcontexts->dbase);
 
 		/* SEUsers */
@@ -1302,6 +1360,43 @@
 	if (retval < 0)
 		goto cleanup;
 
+	retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
+			semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL),
+			sh->conf->file_mode);
+	if (retval < 0) {
+		goto cleanup;
+	}
+
+	path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL);
+	if (access(path, F_OK) == 0) {
+		retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
+							semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL),
+							sh->conf->file_mode);
+		if (retval < 0) {
+			goto cleanup;
+		}
+	}
+
+	path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC);
+	if (access(path, F_OK) == 0) {
+		retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
+							semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
+							sh->conf->file_mode);
+		if (retval < 0) {
+			goto cleanup;
+		}
+	}
+
+	path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
+	if (access(path, F_OK) == 0) {
+		retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
+							semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS),
+							sh->conf->file_mode);
+		if (retval < 0) {
+			goto cleanup;
+		}
+	}
+
 	/* run genhomedircon if its enabled, this should be the last operation
 	 * which requires the out policydb */
 	if (!sh->conf->disable_genhomedircon) {
@@ -1321,11 +1416,6 @@
 	sepol_policydb_free(out);
 	out = NULL;
 
-	/* remove files that are automatically generated and no longer needed */
-	unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL));
-	unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL));
-	unlink(semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA));
-
 	if (sh->do_rebuild || modified || bools_modified || fcontexts_modified) {
 		retval = semanage_install_sandbox(sh);
 	}
@@ -1432,19 +1522,12 @@
 	char *data = NULL;
 	ssize_t data_len = 0;
 	int compressed = 0;
-	int in_fd = -1;
 	char *path = NULL;
 	char *filename;
-	char *lang_ext;
+	char *lang_ext = NULL;
 	char *separator;
 
-	if ((in_fd = open(install_filename, O_RDONLY)) == -1) {
-		ERR(sh, "Unable to open %s: %s\n", install_filename, strerror(errno));
-		retval = -1;
-		goto cleanup;
-	}
-
-	if ((data_len = map_file(sh, in_fd, &data, &compressed)) <= 0) {
+	if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 0) {
 		ERR(sh, "Unable to read file %s\n", install_filename);
 		retval = -1;
 		goto cleanup;
@@ -1467,30 +1550,114 @@
 			goto cleanup;
 		}
 		*separator = '\0';
+		lang_ext = separator + 1;
 	}
 
 	separator = strrchr(filename, '.');
 	if (separator == NULL) {
-		ERR(sh, "Module does not have a valid extension.");
-		retval = -1;
-		goto cleanup;
+		if (lang_ext == NULL) {
+			ERR(sh, "Module does not have a valid extension.");
+			retval = -1;
+			goto cleanup;
+		}
+	} else {
+		*separator = '\0';
+		lang_ext = separator + 1;
 	}
-	*separator = '\0';
-
-	lang_ext = separator + 1;
 
 	retval = semanage_direct_install(sh, data, data_len, filename, lang_ext);
 
 cleanup:
-	if (in_fd != -1) {
-		close(in_fd);
-	}
 	if (data_len > 0) munmap(data, data_len);
 	free(path);
 
 	return retval;
 }
 
+static int semanage_direct_extract(semanage_handle_t * sh,
+				   semanage_module_key_t *modkey,
+				   int extract_cil,
+				   void **mapped_data,
+				   size_t *data_len,
+				   semanage_module_info_t **modinfo)
+{
+	char module_path[PATH_MAX];
+	char input_file[PATH_MAX];
+	enum semanage_module_path_type file_type;
+	int rc = -1;
+	semanage_module_info_t *_modinfo = NULL;
+	ssize_t _data_len;
+	char *_data;
+	int compressed;
+
+	/* get path of module */
+	rc = semanage_module_get_path(
+			sh,
+			(const semanage_module_info_t *)modkey,
+			SEMANAGE_MODULE_PATH_NAME,
+			module_path,
+			sizeof(module_path));
+	if (rc != 0) {
+		goto cleanup;
+	}
+
+	if (access(module_path, F_OK) != 0) {
+		ERR(sh, "Module does not exist: %s", module_path);
+		rc = -1;
+		goto cleanup;
+	}
+
+	rc = semanage_module_get_module_info(sh,
+			modkey,
+			&_modinfo);
+	if (rc != 0) {
+		goto cleanup;
+	}
+
+	if (extract_cil || strcmp(_modinfo->lang_ext, "cil") == 0) {
+		file_type = SEMANAGE_MODULE_PATH_CIL;
+	} else {
+		file_type = SEMANAGE_MODULE_PATH_HLL;
+	}
+
+	/* get path of what to extract */
+	rc = semanage_module_get_path(
+			sh,
+			_modinfo,
+			file_type,
+			input_file,
+			sizeof(input_file));
+	if (rc != 0) {
+		goto cleanup;
+	}
+
+	if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && access(input_file, F_OK) != 0) {
+		rc = semanage_compile_module(sh, _modinfo);
+		if (rc < 0) {
+			goto cleanup;
+		}
+	}
+
+	_data_len = map_file(sh, input_file, &_data, &compressed);
+	if (_data_len <= 0) {
+		ERR(sh, "Error mapping file: %s", input_file);
+		rc = -1;
+		goto cleanup;
+	}
+
+	*modinfo = _modinfo;
+	*data_len = (size_t)_data_len;
+	*mapped_data = _data;
+
+cleanup:
+	if (rc != 0) {
+		semanage_module_info_destroy(sh, _modinfo);
+		free(_modinfo);
+	}
+
+	return rc;
+}
+
 /* Removes a module from the sandbox.  Returns 0 on success, -1 if out
  * of memory, -2 if module not found or could not be removed. */
 static int semanage_direct_remove(semanage_handle_t * sh, char *module_name)
diff --git a/libsemanage/src/interfaces_policydb.c b/libsemanage/src/interfaces_policydb.c
index 6a42eed..552ce7d 100644
--- a/libsemanage/src/interfaces_policydb.c
+++ b/libsemanage/src/interfaces_policydb.c
@@ -51,10 +51,8 @@
 {
 
 	if (dbase_policydb_init(handle,
-				semanage_final_path(SEMANAGE_FINAL_SELINUX,
-						    SEMANAGE_KERNEL),
-				semanage_final_path(SEMANAGE_FINAL_TMP,
-						    SEMANAGE_KERNEL),
+				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
 				&SEMANAGE_IFACE_RTABLE,
 				&SEMANAGE_IFACE_POLICYDB_RTABLE,
 				&dconfig->dbase) < 0)
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
index 70f57f9..34b553d 100644
--- a/libsemanage/src/libsemanage.map
+++ b/libsemanage/src/libsemanage.map
@@ -30,6 +30,7 @@
 LIBSEMANAGE_1.1 {
   global:
 	  semanage_module_install;
+	  semanage_module_extract;
 	  semanage_get_hll_compiler_path;
 	  semanage_get_ignore_module_cache;
 	  semanage_set_ignore_module_cache;
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
index d29c346..90c5e49 100644
--- a/libsemanage/src/modules.c
+++ b/libsemanage/src/modules.c
@@ -142,6 +142,23 @@
 	return sh->funcs->install_file(sh, module_name);
 }
 
+int semanage_module_extract(semanage_handle_t * sh,
+				 semanage_module_key_t *modkey,
+				 int extract_cil,
+				 void **mapped_data,
+				 size_t *data_len,
+				 semanage_module_info_t **modinfo) {
+	if (sh->funcs->extract == NULL) {
+		ERR(sh,
+		    "No get function defined for this connection type.");
+		return -1;
+	} else if (!sh->is_connected) {
+		ERR(sh, "Not connected.");
+		return -1;
+	}
+	return sh->funcs->extract(sh, modkey, extract_cil, mapped_data, data_len, modinfo);
+}
+
 /* Legacy function that remains to preserve ABI
  * compatibility. Please use semanage_module_install instead.
  */
@@ -673,10 +690,12 @@
 {
 	assert(sh);
 
-	if (modkey) {
-		free(modkey->name);
+	if (!modkey) {
+		return 0;
 	}
 
+	free(modkey->name);
+
 	return semanage_module_key_init(sh, modkey);
 }
 
diff --git a/libsemanage/src/nodes_policydb.c b/libsemanage/src/nodes_policydb.c
index 56012fb..7224f00 100644
--- a/libsemanage/src/nodes_policydb.c
+++ b/libsemanage/src/nodes_policydb.c
@@ -50,10 +50,8 @@
 {
 
 	if (dbase_policydb_init(handle,
-				semanage_final_path(SEMANAGE_FINAL_SELINUX,
-						    SEMANAGE_KERNEL),
-				semanage_final_path(SEMANAGE_FINAL_TMP,
-						    SEMANAGE_KERNEL),
+				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
 				&SEMANAGE_NODE_RTABLE,
 				&SEMANAGE_NODE_POLICYDB_RTABLE,
 				&dconfig->dbase) < 0)
diff --git a/libsemanage/src/policy.h b/libsemanage/src/policy.h
index c5aec38..f127156 100644
--- a/libsemanage/src/policy.h
+++ b/libsemanage/src/policy.h
@@ -52,6 +52,14 @@
 	/* Install a policy module */
 	int (*install_file) (struct semanage_handle *, const char *);
 
+	/* Extract a policy module */
+	int (*extract) (struct semanage_handle *,
+				 semanage_module_key_t *,
+				 int extract_cil,
+				 void **,
+				 size_t *,
+				 semanage_module_info_t **);
+
 	/* Remove a policy module */
 	int (*remove) (struct semanage_handle *, char *);
 
diff --git a/libsemanage/src/ports_policydb.c b/libsemanage/src/ports_policydb.c
index b9600f0..37d7deb 100644
--- a/libsemanage/src/ports_policydb.c
+++ b/libsemanage/src/ports_policydb.c
@@ -50,10 +50,8 @@
 {
 
 	if (dbase_policydb_init(handle,
-				semanage_final_path(SEMANAGE_FINAL_SELINUX,
-						    SEMANAGE_KERNEL),
-				semanage_final_path(SEMANAGE_FINAL_TMP,
-						    SEMANAGE_KERNEL),
+				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
 				&SEMANAGE_PORT_RTABLE,
 				&SEMANAGE_PORT_POLICYDB_RTABLE,
 				&dconfig->dbase) < 0)
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 6051691..fa0876f 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -110,10 +110,14 @@
 	"/disable_dontaudit",
 	"/preserve_tunables",
 	"/modules/disabled",
+	"/policy.kern",
+	"/file_contexts.local",
+	"/file_contexts",
+	"/seusers"
 };
 
 static char const * const semanage_final_prefix[SEMANAGE_FINAL_NUM] = {
-	"/tmp",
+	"/final",
 	"",
 };
 
@@ -664,7 +668,7 @@
 
 /* Copies a file from src to dst.  If dst already exists then
  * overwrite it.  Returns 0 on success, -1 on error. */
-static int semanage_copy_file(const char *src, const char *dst, mode_t mode)
+int semanage_copy_file(const char *src, const char *dst, mode_t mode)
 {
 	int in, out, retval = 0, amount_read, n, errsv = errno;
 	char tmp[PATH_MAX];
@@ -943,9 +947,7 @@
 		goto cleanup;
 	}
 
-	/* Copy in exported databases.
-	 * i = 1 to avoid copying the top level directory.
-	 */
+	// Build final directory structure
 	int i;
 	for (i = 1; i < SEMANAGE_FINAL_PATH_NUM; i++) {
 		if (strlen(semanage_final_path(SEMANAGE_FINAL_TMP, i)) >= sizeof(fn)) {
@@ -959,12 +961,6 @@
 			status = -1;
 			goto cleanup;
 		}
-
-		semanage_copy_file(
-			semanage_final_path(SEMANAGE_FINAL_SELINUX, i),
-			semanage_final_path(SEMANAGE_FINAL_TMP, i),
-			sh->conf->file_mode);
-		/* ignore errors, these files may not exist */
 	}
 
 cleanup:
@@ -1431,11 +1427,11 @@
 		goto cleanup;
 	}
 
-	fc = open(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
+	fc = open(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
 		  O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
 	if (fc < 0) {
 		ERR(sh, "Could not open %s for writing.",
-		    semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC));
+		    semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC));
 		goto cleanup;
 	}
 	hd = open(semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL),
@@ -1460,8 +1456,7 @@
 		} else {
 			if (write(fc, buf, strlen(buf)) < 0) {
 				ERR(sh, "Write to %s failed.",
-				    semanage_final_path(SEMANAGE_FINAL_TMP,
-							SEMANAGE_FC));
+				    semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC));
 				goto cleanup;
 			}
 		}
@@ -2019,8 +2014,7 @@
 	FILE *infile = NULL;
 
 	if ((kernel_filename =
-	     semanage_final_path(SEMANAGE_FINAL_SELINUX,
-				 SEMANAGE_KERNEL)) == NULL) {
+	     semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL)) == NULL) {
 		goto cleanup;
 	}
 	if ((infile = fopen(kernel_filename, "r")) == NULL) {
@@ -2061,7 +2055,7 @@
 	FILE *outfile = NULL;
 
 	if ((kernel_filename =
-	     semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL)) == NULL) {
+	     semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL)) == NULL) {
 		goto cleanup;
 	}
 	if ((outfile = fopen(kernel_filename, "wb")) == NULL) {
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index 62c7079..acb6e3f 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -55,6 +55,10 @@
 	SEMANAGE_DISABLE_DONTAUDIT,
 	SEMANAGE_PRESERVE_TUNABLES,
 	SEMANAGE_MODULES_DISABLED,
+	SEMANAGE_STORE_KERNEL,
+	SEMANAGE_STORE_FC_LOCAL,
+	SEMANAGE_STORE_FC,
+	SEMANAGE_STORE_SEUSERS,
 	SEMANAGE_STORE_NUM_PATHS
 };
 
@@ -148,4 +152,6 @@
 		     size_t buf_len,
 		     char **sorted_buf, size_t * sorted_buf_len);
 
+int semanage_copy_file(const char *src, const char *dst, mode_t mode);
+
 #endif
diff --git a/libsemanage/src/semanageswig_python.i b/libsemanage/src/semanageswig_python.i
index 06b9408..1346b2e 100644
--- a/libsemanage/src/semanageswig_python.i
+++ b/libsemanage/src/semanageswig_python.i
@@ -23,6 +23,7 @@
 %header %{
 	#include <stdlib.h>
 	#include <semanage/semanage.h>
+	#include <sys/mman.h>
 
 	#define STATUS_SUCCESS 0
 	#define STATUS_ERR -1
@@ -103,6 +104,10 @@
 %apply int *OUTPUT { unsigned int * };
 %apply int *OUTPUT { uint16_t * };
 
+%include <cstring.i>
+/* This is needed to properly mmaped binary data in SWIG */
+%cstring_output_allocate_size(void **mapped_data, size_t *data_len, munmap(*$1, *$2));
+
 %typemap(in, numinputs=0) char **(char *temp=NULL) {
 	$1 = &temp;
 }
diff --git a/libsemanage/src/users_base_policydb.c b/libsemanage/src/users_base_policydb.c
index 0a6ab9c..b42279c 100644
--- a/libsemanage/src/users_base_policydb.c
+++ b/libsemanage/src/users_base_policydb.c
@@ -50,10 +50,8 @@
 {
 
 	if (dbase_policydb_init(handle,
-				semanage_final_path(SEMANAGE_FINAL_SELINUX,
-						    SEMANAGE_KERNEL),
-				semanage_final_path(SEMANAGE_FINAL_TMP,
-						    SEMANAGE_KERNEL),
+				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
 				&SEMANAGE_USER_BASE_RTABLE,
 				&SEMANAGE_USER_BASE_POLICYDB_RTABLE,
 				&dconfig->dbase) < 0)
diff --git a/libsemanage/utils/semanage_migrate_store b/libsemanage/utils/semanage_migrate_store
index 2f85e9c..0ebd285 100755
--- a/libsemanage/utils/semanage_migrate_store
+++ b/libsemanage/utils/semanage_migrate_store
@@ -10,7 +10,7 @@
 
 import ctypes
 
-sepol = ctypes.cdll.LoadLibrary('libsepol.so')
+sepol = ctypes.cdll.LoadLibrary('libsepol.so.1')
 
 try:
 	import selinux
@@ -180,7 +180,7 @@
 
 
 def oldroot_path():
-	return "/etc/selinux"
+	return "%s/etc/selinux" % ROOT
 
 def oldstore_path(store):
 	return "%s/%s/modules/active" % (oldroot_path(), store)
@@ -192,7 +192,7 @@
 	return "%s/disabled" % newmodules_path(store)
 
 def newroot_path():
-	return PATH
+	return "%s%s" % (ROOT, PATH)
 
 def newstore_path(store):
 	return "%s/%s/active" % (newroot_path(), store)
@@ -219,6 +219,8 @@
 			  help="Disable rebuilding policy after migration (default: no)")
 	parser.add_option("-P", "--path", dest="path",
 			  help="Set path for the policy store (default: /var/lib/selinux)")
+	parser.add_option("-r", "--root", dest="root",
+			  help="Set an alternative root for the migration (default: /)")
 
 	(options, args) = parser.parse_args()
 
@@ -231,6 +233,10 @@
 	if PATH is None:
 		PATH = "/var/lib/selinux"
 
+	ROOT = options.root
+	if ROOT is None:
+		ROOT = ""
+
 	# List of paths that go in the active 'root'
 	TOPPATHS = [
 		"commit_num",
@@ -241,9 +247,13 @@
 		"file_contexts.local",
 		"seusers",
 		"users.local",
+		"users_extra",
 		"users_extra.local",
 		"disable_dontaudit",
-		"preserve_tunables" ]
+		"preserve_tunables",
+		"policy.kern",
+		"file_contexts",
+		"homedir_template"]
 
 
 	create_dir(newroot_path(), 0o755)
diff --git a/libsepol/Android.mk b/libsepol/Android.mk
index 45eaafc..430d859 100644
--- a/libsepol/Android.mk
+++ b/libsepol/Android.mk
@@ -46,6 +46,7 @@
 	cil/src/cil_build_ast.c \
 	cil/src/cil.c \
 	cil/src/cil_copy_ast.c \
+	cil/src/cil_find.c \
 	cil/src/cil_fqn.c \
 	cil/src/cil_lexer.l \
 	cil/src/cil_list.c \
diff --git a/libsepol/ChangeLog b/libsepol/ChangeLog
index 26b99dc..c5c97f2 100644
--- a/libsepol/ChangeLog
+++ b/libsepol/ChangeLog
@@ -1,8 +1,25 @@
+	* Add neverallow support for ioctl extended permissions, from Jeff Vander Stoep.
+	* Improve CIL block and macro call recursion detection, from Steve Lawrence
+	* Fix CIL uninitialized false positive in cil_binary, from Yuli Khodorkovskiy
+	* Provide error in CIL if classperms are empty, from Yuli Khodorkovskiy
+	* Add userattribute{set} functionality to CIL, from Yuli Khodorkovskiy
+	* fix CIL blockinherit copying segfault and add macro restrictions, from Steve Lawrence
+	* fix CIL NULL pointer dereference when copying classpermission/set, from Steve Lawrence
+	* Add CIL support for ioctl whitelists, from Steve Lawrence
+	* Fix memory leak when destroying avtab, from Steve Lawrence
+	* Replace sscanf in module_to_cil, from Yuli Khodorkovskiy.
+	* Improve CIL resolution error messages, from Steve Lawrence
+	* Fix policydb_read for policy versions < 24, from Stephen Smalley.
+	* Added CIL bounds checking and refactored CIL Neverallow checking, from James Carter
+	* Refactored libsepol Neverallow and bounds (hierarchy) checking, from James Carter
+	* Treat types like an attribute in the attr_type_map, from James Carter
+	* Add new ebitmap function named ebitmap_match_any(), from James Carter
+	* switch operations to extended perms, from Jeff Vander Stoep.
 	* Write auditadm_r and secadm_r roles to base module when writing CIL, from Steve Lawrence
 	* Fix module to CIL to only associate declared roleattributes with in-scope types, from Steve Lawrence
 	* Don't allow categories/sensitivities inside blocks in CIL, from Yuli Khodorkovskiy.
 	* Replace fmemopen() with internal function in libsepol, from James Carter.
-	* Verify users prior to evaluating users in cil, from Yuli Khodorkovskiy. 
+	* Verify users prior to evaluating users in cil, from Yuli Khodorkovskiy.
 	* Binary modules do not support ioctl rules, from Stephen Smalley.
 	* Add support for ioctl command whitelisting, from Jeff Vander Stoep.
 	* Don't use symbol versioning for static object files, from Yuli Khodorkovskiy.
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 5c53bf3..8716deb 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -70,11 +70,11 @@
 #endif
 
 int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
-	{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
-	{64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
-	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+	{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
+	{64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
+	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
 };
 
 static void cil_init_keys(void)
@@ -122,6 +122,8 @@
 	CIL_KEY_TYPE = cil_strpool_add("type");
 	CIL_KEY_ROLE = cil_strpool_add("role");
 	CIL_KEY_USER = cil_strpool_add("user");
+	CIL_KEY_USERATTRIBUTE = cil_strpool_add("userattribute");
+	CIL_KEY_USERATTRIBUTESET = cil_strpool_add("userattributeset");
 	CIL_KEY_SENSITIVITY = cil_strpool_add("sensitivity");
 	CIL_KEY_CATEGORY = cil_strpool_add("category");
 	CIL_KEY_CATSET = cil_strpool_add("categoryset");
@@ -223,6 +225,11 @@
 	CIL_KEY_ROOT = cil_strpool_add("<root>");
 	CIL_KEY_NODE = cil_strpool_add("<node>");
 	CIL_KEY_PERM = cil_strpool_add("perm");
+	CIL_KEY_ALLOWX = cil_strpool_add("allowx");
+	CIL_KEY_AUDITALLOWX = cil_strpool_add("auditallowx");
+	CIL_KEY_DONTAUDITX = cil_strpool_add("dontauditx");
+	CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx");
+	CIL_KEY_IOCTL = cil_strpool_add("ioctl");
 }
 
 void cil_db_init(struct cil_db **db)
@@ -257,12 +264,15 @@
 	cil_type_init(&(*db)->selftype);
 	(*db)->selftype->datum.name = CIL_KEY_SELF;
 	(*db)->selftype->datum.fqn = CIL_KEY_SELF;
-
+	(*db)->num_types_and_attrs = 0;
+	(*db)->num_classes = 0;
 	(*db)->num_types = 0;
 	(*db)->num_roles = 0;
+	(*db)->num_users = 0;
 	(*db)->num_cats = 0;
 	(*db)->val_to_type = NULL;
 	(*db)->val_to_role = NULL;
+	(*db)->val_to_user = NULL;
 
 	(*db)->disable_dontaudit = CIL_FALSE;
 	(*db)->disable_neverallow = CIL_FALSE;
@@ -305,6 +315,7 @@
 	cil_strpool_destroy();
 	free((*db)->val_to_type);
 	free((*db)->val_to_role);
+	free((*db)->val_to_user);
 
 	free(*db);
 	*db = NULL;	
@@ -340,7 +351,7 @@
 
 	rc = cil_parser(name, buffer, size + 2, &db->parse);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Failed to parse %s\n", name);
+		cil_log(CIL_INFO, "Failed to parse %s\n", name);
 		goto exit;
 	}
 
@@ -370,7 +381,7 @@
 	cil_log(CIL_INFO, "Building AST from Parse Tree\n");
 	rc = cil_build_ast(db, db->parse->root, db->ast->root);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Failed to build ast\n");
+		cil_log(CIL_INFO, "Failed to build ast\n");
 		goto exit;
 	}
 
@@ -380,21 +391,21 @@
 	cil_log(CIL_INFO, "Resolving AST\n");
 	rc = cil_resolve_ast(db, db->ast->root);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Failed to resolve ast\n");
+		cil_log(CIL_INFO, "Failed to resolve ast\n");
 		goto exit;
 	}
 
 	cil_log(CIL_INFO, "Qualifying Names\n");
 	rc = cil_fqn_qualify(db->ast->root);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Failed to qualify names\n");
+		cil_log(CIL_INFO, "Failed to qualify names\n");
 		goto exit;
 	}
 
 	cil_log(CIL_INFO, "Compile post process\n");
 	rc = cil_post_process(db);
 	if (rc != SEPOL_OK ) {
-		cil_log(CIL_ERR, "Post process failed\n");
+		cil_log(CIL_INFO, "Post process failed\n");
 		goto exit;
 	}
 
@@ -546,6 +557,12 @@
 	case CIL_USER:
 		cil_destroy_user(*data);
 		break;
+	case CIL_USERATTRIBUTE:
+		cil_destroy_userattribute(*data);
+		break;
+	case CIL_USERATTRIBUTESET:
+		cil_destroy_userattributeset(*data);
+		break;
 	case CIL_USERPREFIX:
 		cil_destroy_userprefix(*data);
 		break;
@@ -652,6 +669,12 @@
 	case CIL_AVRULE:
 		cil_destroy_avrule(*data);
 		break;
+	case CIL_AVRULEX:
+		cil_destroy_avrulex(*data);
+		break;
+	case CIL_PERMISSIONX:
+		cil_destroy_permissionx(*data);
+		break;
 	case CIL_ROLETRANSITION:
 		cil_destroy_roletransition(*data);
 		break;
@@ -782,6 +805,7 @@
 		*sym_index = CIL_SYM_CLASSPERMSETS;
 		break;
 	case CIL_USER:
+	case CIL_USERATTRIBUTE:
 		*sym_index = CIL_SYM_USERS;
 		break;
 	case CIL_ROLE:
@@ -823,6 +847,9 @@
 	case CIL_POLICYCAP:
 		*sym_index = CIL_SYM_POLICYCAPS;
 		break;
+	case CIL_PERMISSIONX:
+		*sym_index = CIL_SYM_PERMX;
+		break;
 	default:
 		*sym_index = CIL_SYM_UNKNOWN;
 		cil_log(CIL_INFO, "Failed to find flavor: %d\n", flavor);
@@ -909,6 +936,10 @@
 		return CIL_KEY_CLASSPERMISSIONSET;
 	case CIL_USER:
 		return CIL_KEY_USER;
+	case CIL_USERATTRIBUTE:
+		return CIL_KEY_USERATTRIBUTE;
+	case CIL_USERATTRIBUTESET:
+		return CIL_KEY_USERATTRIBUTESET;
 	case CIL_USERPREFIX:
 		return CIL_KEY_USERPREFIX;
 	case CIL_USERROLE:
@@ -993,6 +1024,20 @@
 			break;
 		}
 		break;
+	case CIL_AVRULEX:
+		switch (((struct cil_avrulex *)node->data)->rule_kind) {
+		case CIL_AVRULE_ALLOWED:
+			return CIL_KEY_ALLOWX;
+		case CIL_AVRULE_AUDITALLOW:
+			return CIL_KEY_AUDITALLOWX;
+		case CIL_AVRULE_DONTAUDIT:
+			return CIL_KEY_DONTAUDITX;
+		default:
+			break;
+		}
+		break;
+	case CIL_PERMISSIONX:
+		return CIL_KEY_PERMISSIONX;
 	case CIL_ROLETRANSITION:
 		return CIL_KEY_ROLETRANSITION;
 	case CIL_TYPE_RULE:
@@ -2078,6 +2123,31 @@
 	(*avrule)->classperms = NULL;
 }
 
+void cil_permissionx_init(struct cil_permissionx **permx)
+{
+	*permx = cil_malloc(sizeof(**permx));
+
+	cil_symtab_datum_init(&(*permx)->datum);
+	(*permx)->kind = CIL_NONE;
+	(*permx)->obj_str = NULL;
+	(*permx)->obj = NULL;
+	(*permx)->expr_str = NULL;
+	(*permx)->perms = NULL;
+}
+
+void cil_avrulex_init(struct cil_avrulex **avrule)
+{
+	*avrule = cil_malloc(sizeof(**avrule));
+
+	(*avrule)->rule_kind = CIL_NONE;
+	(*avrule)->src_str = NULL;
+	(*avrule)->src = NULL;
+	(*avrule)->tgt_str = NULL;
+	(*avrule)->tgt = NULL;
+	(*avrule)->permx_str = NULL;
+	(*avrule)->permx = NULL;
+}
+
 void cil_type_rule_init(struct cil_type_rule **type_rule)
 {
 	*type_rule = cil_malloc(sizeof(**type_rule));
@@ -2325,6 +2395,26 @@
 	(*user)->roles = NULL;
 	(*user)->dftlevel = NULL;
 	(*user)->range = NULL;
+	(*user)->value = 0;
+}
+
+void cil_userattribute_init(struct cil_userattribute **attr)
+{
+	*attr = cil_malloc(sizeof(**attr));
+
+	cil_symtab_datum_init(&(*attr)->datum);
+
+	(*attr)->expr_list = NULL;
+	(*attr)->users = NULL;
+}
+
+void cil_userattributeset_init(struct cil_userattributeset **attrset)
+{
+	*attrset = cil_malloc(sizeof(**attrset));
+
+	(*attrset)->attr_str = NULL;
+	(*attrset)->str_expr = NULL;
+	(*attrset)->datum_expr = NULL;
 }
 
 void cil_userlevel_init(struct cil_userlevel **usrlvl)
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index 03f4924..db09ec5 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -37,6 +37,8 @@
 #include <sepol/policydb/conditional.h>
 #include <sepol/policydb/constraint.h>
 #include <sepol/policydb/flask.h>
+#include <sepol/policydb/expand.h>
+#include <sepol/policydb/hierarchy.h>
 
 #include "cil_internal.h"
 #include "cil_flavor.h"
@@ -45,13 +47,16 @@
 #include "cil_tree.h"
 #include "cil_binary.h"
 #include "cil_symtab.h"
+#include "cil_find.h"
 
 /* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended
  * size of a hashtable. The next power of 2 of this is 2 ** 16.
  */
-#define FILENAME_TRANS_TABLE_SIZE 1 << 16
-#define RANGE_TRANS_TABLE_SIZE 1 << 13
-#define ROLE_TRANS_TABLE_SIZE 1 << 10
+#define FILENAME_TRANS_TABLE_SIZE (1 << 16)
+#define RANGE_TRANS_TABLE_SIZE (1 << 13)
+#define ROLE_TRANS_TABLE_SIZE (1 << 10)
+#define AVRULEX_TABLE_SIZE (1 <<  10)
+#define PERMS_PER_CLASS 32
 
 struct cil_args_binary {
 	const struct cil_db *db;
@@ -61,6 +66,8 @@
 	hashtab_t filename_trans_table;
 	hashtab_t range_trans_table;
 	hashtab_t role_trans_table;
+	hashtab_t avrulex_ioctl_table;
+	void **type_value_to_cil;
 };
 
 struct cil_args_booleanif {
@@ -68,39 +75,9 @@
 	policydb_t *pdb;
 	cond_node_t *cond_node;
 	enum cil_flavor cond_flavor;
-	struct cil_list *neverallows;
 	hashtab_t filename_trans_table;
 };
 
-struct cil_neverallow {
-	struct cil_tree_node *node;
-	struct cil_list *rules;
-};
-
-struct cil_neverallow_rule {
-	struct cil_symtab_datum *src;
-	struct cil_symtab_datum *tgt;
-	uint32_t class;
-	uint32_t perms;
-};
-
-void cil_neverallows_list_destroy(struct cil_list *neverallows)
-{
-	struct cil_list_item *i;
-	struct cil_list_item *j;
-
-	cil_list_for_each(i, neverallows) {
-		struct cil_neverallow *neverallow = i->data;
-		cil_list_for_each(j, neverallow->rules) {
-			struct cil_neverallow_rule *rule = j->data;
-			free(rule);
-		}
-		cil_list_destroy(&neverallow->rules, CIL_FALSE);
-		free(neverallow);
-	}
-	cil_list_destroy(&neverallows, CIL_FALSE);
-}
-
 static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user)
 {
 	*sepol_user = hashtab_search(pdb->p_users.table, datum->fqn);
@@ -167,6 +144,34 @@
 	return SEPOL_OK;
 }
 
+static int __cil_expand_user(struct cil_symtab_datum *datum, ebitmap_t *new)
+{
+	struct cil_tree_node *node = datum->nodes->head->data;
+	struct cil_user *user = NULL;
+	struct cil_userattribute *attr = NULL;
+
+	if (node->flavor == CIL_USERATTRIBUTE) {
+		attr = (struct cil_userattribute *)datum;
+		if (ebitmap_cpy(new, attr->users)) {
+			cil_log(CIL_ERR, "Failed to copy user bits\n");
+			goto exit;
+		}
+	} else {
+		user = (struct cil_user *)datum;
+		ebitmap_init(new);
+		if (ebitmap_set_bit(new, user->value, 1)) {
+			cil_log(CIL_ERR, "Failed to set user bit\n");
+			ebitmap_destroy(new);
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return SEPOL_ERR;
+}
+
 static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new)
 {
 	struct cil_tree_node *node = datum->nodes->head->data;
@@ -330,7 +335,7 @@
 	return rc;
 }
 
-int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
+int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 	struct cil_list_item *curr_class;
@@ -339,8 +344,8 @@
 		struct cil_class *cil_class = curr_class->data;
 		uint32_t value = 0;
 		char *key = NULL;
-		struct cil_tree_node *node = cil_class->datum.nodes->head->data;
-		struct cil_tree_node *cil_perm = node->cl_head;
+		int class_index;
+		struct cil_tree_node *curr;
 		common_datum_t *sepol_common = NULL;
 		class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class));
 		memset(sepol_class, 0, sizeof(class_datum_t));
@@ -353,6 +358,8 @@
 			goto exit;
 		}
 		sepol_class->s.value = value;
+		class_index = value;
+		class_value_to_cil[class_index] = cil_class;
 
 		rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE);
 		if (rc != SEPOL_OK) {
@@ -360,6 +367,7 @@
 		}
 
 		if (cil_class->common != NULL) {
+			int i;
 			struct cil_class *cil_common = cil_class->common;
 
 			key = cil_class->common->datum.fqn;
@@ -373,14 +381,19 @@
 			sepol_class->comdatum = sepol_common;
 			sepol_class->comkey = cil_strdup(key);
 			sepol_class->permissions.nprim += sepol_common->permissions.nprim;
+
+			for (curr = NODE(cil_class->common)->cl_head, i = 1; curr; curr = curr->next, i++) {
+				struct cil_perm *cil_perm = curr->data;
+				perm_value_to_cil[class_index][i] = cil_perm;
+			}
 		}
 
-		while (cil_perm != NULL) {
-			struct cil_perm *curr_perm = cil_perm->data;
+		for (curr = NODE(cil_class)->cl_head; curr; curr = curr->next) {
+			struct cil_perm *cil_perm = curr->data;
 			perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
 			memset(sepol_perm, 0, sizeof(perm_datum_t));
 
-			key = cil_strdup(curr_perm->datum.fqn);
+			key = cil_strdup(cil_perm->datum.fqn);
 			rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm);
 			if (rc != SEPOL_OK) {
 				free(sepol_perm);
@@ -389,7 +402,7 @@
 			}
 			sepol_perm->s.value = sepol_class->permissions.nprim + 1;
 			sepol_class->permissions.nprim++;
-			cil_perm = cil_perm->next;
+			perm_value_to_cil[class_index][sepol_perm->s.value] = cil_perm;
 		}
 	}
 
@@ -490,7 +503,7 @@
 	return rc;
 }
 
-int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
+int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 	uint32_t value = 0;
@@ -508,6 +521,8 @@
 	sepol_type->s.value = value;
 	sepol_type->primary = 1;
 
+	type_value_to_cil[value] = cil_type;
+
 	return SEPOL_OK;
 
 exit:
@@ -591,7 +606,7 @@
 
 }
 
-int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr)
+int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 	uint32_t value = 0;
@@ -615,6 +630,8 @@
 	sepol_attr->s.value = value;
 	sepol_attr->primary = 1;
 
+	type_value_to_cil[value] = cil_attr;
+
 	return SEPOL_OK;
 
 exit:
@@ -628,14 +645,21 @@
 	int rc = SEPOL_ERR;
 
 	pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
+	pdb->attr_type_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
 
 	uint32_t i = 0;
 	for (i = 0; i < pdb->p_types.nprim; i++) {
 		ebitmap_init(&pdb->type_attr_map[i]);
+		ebitmap_init(&pdb->attr_type_map[i]);
 		if (ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) {
 			rc = SEPOL_ERR;
 			goto exit;
 		}
+		if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) {
+			rc = SEPOL_ERR;
+			goto exit;
+		}
+
 	}
 
 	return SEPOL_OK;
@@ -675,6 +699,7 @@
 		if (rc != SEPOL_OK) goto exit;
 
 		ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1);
+		ebitmap_set_bit(&pdb->attr_type_map[value - 1], sepol_type->s.value - 1, 1);
 	}
 
 	rc = SEPOL_OK;
@@ -749,43 +774,41 @@
 	return SEPOL_ERR;
 }
 
-int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole)
+int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user)
 {
 	int rc = SEPOL_ERR;
 	user_datum_t *sepol_user = NULL;
 	role_datum_t *sepol_role = NULL;
-	ebitmap_t role_bitmap;
-	ebitmap_node_t *rnode;
+	ebitmap_node_t *rnode = NULL;
 	unsigned int i;
 
-	rc = __cil_get_sepol_user_datum(pdb, DATUM(userrole->user), &sepol_user);
-	if (rc != SEPOL_OK) goto exit;
-
-	rc = __cil_expand_role(userrole->role, &role_bitmap);
-	if (rc != SEPOL_OK) goto exit;
-
-	ebitmap_for_each_bit(&role_bitmap, rnode, i) {
-		if (!ebitmap_get_bit(&role_bitmap, i)) continue;
-
-		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
-		if (rc != SEPOL_OK) goto exit;
-
-		if (sepol_role->s.value == 1) {
-			// role is object_r, ignore it since it is implicitly associated
-			// with all users
-			continue;
+	if (user->roles) {
+		rc = __cil_get_sepol_user_datum(pdb, DATUM(user), &sepol_user);
+		if (rc != SEPOL_OK) {
+			goto exit;
 		}
 
-		if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
-			cil_log(CIL_INFO, "Failed to set role bit for user\n");
-			goto exit;
+		ebitmap_for_each_bit(user->roles, rnode, i) {
+			if (!ebitmap_get_bit(user->roles, i)) {
+				continue;
+			}
+
+			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+
+			if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
+				cil_log(CIL_INFO, "Failed to set role bit for user\n");
+				rc = SEPOL_ERR;
+				goto exit;
+			}
 		}
 	}
 
 	rc = SEPOL_OK;
 
 exit:
-	ebitmap_destroy(&role_bitmap);
 	return rc;
 }
 
@@ -1324,89 +1347,7 @@
 	return rc;
 }
 
-static void __cil_neverallow_handle(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
-{
-	struct cil_neverallow *neverallow = neverallows->head->data;
-	struct cil_list *neverallow_rules = neverallow->rules;
-	struct cil_neverallow_rule *new = NULL;
-
-	new = cil_malloc(sizeof(*new));
-	new->src = src;
-	new->tgt = tgt;
-	new->class = class;
-	new->perms = perms;
-
-	cil_list_append(neverallow_rules, CIL_LIST_ITEM, new);
-}
-
-static int __cil_is_type_match(enum cil_flavor f1, struct cil_symtab_datum *t1, enum cil_flavor f2, struct cil_symtab_datum *t2)
-{
-	if (t1->fqn == t2->fqn) {
-		return CIL_TRUE;
-	} else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
-		struct cil_typeattribute *a = (struct cil_typeattribute *)t1;
-		struct cil_type *t = (struct cil_type *)t2;
-		if (ebitmap_get_bit(a->types, t->value)) {
-			return CIL_TRUE;
-		}
-	} else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
-		struct cil_typeattribute *a = (struct cil_typeattribute *)t2;
-		struct cil_type *t = (struct cil_type *)t1;
-		if (ebitmap_get_bit(a->types, t->value)) {
-			return CIL_TRUE;
-		}
-	} else if (f1 == CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
-		struct cil_typeattribute *a1 = (struct cil_typeattribute *)t2;
-		struct cil_typeattribute *a2 = (struct cil_typeattribute *)t1;
-		/* abusing the ebitmap abstraction for speed */
-		ebitmap_node_t *n1 = a1->types->node;
-		ebitmap_node_t *n2 = a2->types->node;
-		while (n1 && n2) {
-			if (n1->startbit < n2->startbit) {
-				n1 = n1->next;
-			} else if (n2->startbit < n1->startbit) {
-				n2 = n2->next;
-			} else {
-				if (n1->map & n2->map) {
-					return CIL_TRUE;
-				}
-				n1 = n1->next;
-				n2 = n2->next;
-			}
-		}
-	}
-	return CIL_FALSE;
-}
-
-static int __cil_check_neverallows(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
-{
-	struct cil_list_item *curr = NULL;
-	enum cil_flavor al_src_flavor = ((struct cil_tree_node*)src->nodes->head->data)->flavor;
-	enum cil_flavor al_tgt_flavor = ((struct cil_tree_node*)tgt->nodes->head->data)->flavor;
-	cil_list_for_each(curr, neverallows) {
-		struct cil_neverallow *neverallow = curr->data;
-		struct cil_tree_node *node = neverallow->node;
-		struct cil_list_item *curr_item = NULL;
-		cil_list_for_each(curr_item, neverallow->rules) {
-			struct cil_neverallow_rule *curr_rule = curr_item->data;
-			enum cil_flavor nv_src_flavor = ((struct cil_tree_node*)curr_rule->src->nodes->head->data)->flavor;
-			enum cil_flavor nv_tgt_flavor = ((struct cil_tree_node*)curr_rule->tgt->nodes->head->data)->flavor;
-			if ((curr_rule->perms & perms) && (class == curr_rule->class)) {
-				int src_match = __cil_is_type_match(al_src_flavor, src, nv_src_flavor, curr_rule->src);
-				if (src_match) {
-					int tgt_match = __cil_is_type_match(al_tgt_flavor, tgt, nv_tgt_flavor, curr_rule->tgt);
-					if (tgt_match) {
-						cil_log(CIL_ERR, "Neverallow found that matches avrule at line %d of %s\n", node->line, node->path);
-						return SEPOL_ERR;
-					}
-				}
-			}
-		}
-	}
-	return SEPOL_OK;
-}
-
-int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
+int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, cond_node_t *cond_node, enum cil_flavor cond_flavor)
 {
 	int rc = SEPOL_ERR;
 	type_datum_t *sepol_src = NULL;
@@ -1425,28 +1366,19 @@
 		return SEPOL_OK;
 	}
 
-	if (kind == CIL_AVRULE_NEVERALLOW) {
-		__cil_neverallow_handle(neverallows, src, tgt, sepol_class->s.value, data);
-	} else {
-		if (kind == CIL_AVRULE_DONTAUDIT) {
-			data = ~data;
-		} else if (neverallows != NULL && kind == CIL_AVRULE_ALLOWED) {
-			rc = __cil_check_neverallows(neverallows, src, tgt, sepol_class->s.value, data);
-			if (rc != SEPOL_OK) {
-				goto exit;
-			}
-		}
+	if (kind == CIL_AVRULE_DONTAUDIT) {
+		data = ~data;
+	}
 
-		rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
-		if (rc != SEPOL_OK) goto exit;
+	rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
+	if (rc != SEPOL_OK) goto exit;
 
-		rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
-		if (rc != SEPOL_OK) goto exit;
+	rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
+	if (rc != SEPOL_OK) goto exit;
 
-		rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
-		if (rc != SEPOL_OK) {
-			goto exit;
-		}
+	rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
+	if (rc != SEPOL_OK) {
+		goto exit;
 	}
 
 	return SEPOL_OK;
@@ -1456,7 +1388,7 @@
 }
 
 
-int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
+int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, cond_node_t *cond_node, enum cil_flavor cond_flavor)
 {
 	int rc = SEPOL_ERR;
 	struct cil_list_item *curr;
@@ -1465,7 +1397,7 @@
 		if (curr->flavor == CIL_CLASSPERMS) {
 			struct cil_classperms *cp = curr->data;
 			if (FLAVOR(cp->class) == CIL_CLASS) {
-				rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, neverallows, cond_node, cond_flavor);
+				rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, cond_node, cond_flavor);
 				if (rc != SEPOL_OK) {
 					goto exit;
 				}
@@ -1473,7 +1405,7 @@
 				struct cil_list_item *i = NULL;
 				cil_list_for_each(i, cp->perms) {
 					struct cil_perm *cmp = i->data;
-					rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, neverallows, cond_node, cond_flavor);
+					rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, cond_node, cond_flavor);
 					if (rc != SEPOL_OK) {
 						goto exit;
 					}
@@ -1482,7 +1414,7 @@
 		} else { /* SET */
 			struct cil_classperms_set *cp_set = curr->data;
 			struct cil_classpermission *cp = cp_set->set;
-			rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, neverallows, cond_node, cond_flavor);
+			rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, cond_node, cond_flavor);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
@@ -1495,7 +1427,7 @@
 	return rc;
 }
 
-int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
+int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
 {
 	int rc = SEPOL_ERR;
 	uint16_t kind = cil_avrule->rule_kind;
@@ -1509,12 +1441,6 @@
 		goto exit;
 	}
 
-	if (cil_avrule->rule_kind == CIL_AVRULE_NEVERALLOW && db->disable_neverallow == CIL_TRUE) {
-		// ignore neverallow rules
-		rc = SEPOL_OK;
-		goto exit;
-	}
-
 	src = cil_avrule->src;
 	tgt = cil_avrule->tgt;
 
@@ -1530,7 +1456,7 @@
 			if (!ebitmap_get_bit(&type_bitmap, i)) continue;
 
 			src = DATUM(db->val_to_type[i]);
-			rc = __cil_avrule_expand(pdb, kind, src, src, classperms, neverallows, cond_node, cond_flavor);
+			rc = __cil_avrule_expand(pdb, kind, src, src, classperms, cond_node, cond_flavor);
 			if (rc != SEPOL_OK) {
 				ebitmap_destroy(&type_bitmap);
 				goto exit;
@@ -1538,7 +1464,7 @@
 		}
 		ebitmap_destroy(&type_bitmap);
 	} else {
-		rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, neverallows, cond_node, cond_flavor);
+		rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
 		if (rc != SEPOL_OK) goto exit;
 	}
 
@@ -1548,9 +1474,289 @@
 	return rc;
 }
 
-int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows)
+int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule)
 {
-	return __cil_avrule_to_avtab(pdb, db, cil_avrule, neverallows, NULL, CIL_FALSE);
+	return __cil_avrule_to_avtab(pdb, db, cil_avrule, NULL, CIL_FALSE);
+}
+
+// Copied from checkpolicy/policy_define.c
+
+/* index of the u32 containing the permission */
+#define XPERM_IDX(x) (x >> 5)
+/* set bits 0 through x-1 within the u32 */
+#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
+/* low value for this u32 */
+#define XPERM_LOW(x) (x << 5)
+/* high value for this u32 */
+#define XPERM_HIGH(x) (((x + 1) << 5) - 1)
+void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avtab_extended_perms *xperms)
+{
+	unsigned int i;
+	uint16_t h = high + 1;
+	/* for each u32 that this low-high range touches, set driver permissions */
+	for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
+		/* set all bits in u32 */
+		if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+			xperms->perms[i] |= ~0U;
+		/* set low bits */
+		else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
+			xperms->perms[i] |= XPERM_SETBITS(h);
+		/* set high bits */
+		else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
+			xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
+		/* set middle bits */
+		else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
+			xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
+	}
+}
+
+
+#define IOC_DRIV(x) (x >> 8)
+#define IOC_FUNC(x) (x & 0xff)
+
+int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args)
+{
+	int rc = SEPOL_OK;
+	struct policydb *pdb;
+	avtab_key_t *avtab_key;
+	avtab_datum_t avtab_datum;
+	ebitmap_t *xperms;
+	ebitmap_node_t *node;
+	unsigned int i;
+	uint16_t low = 0, high = 0;
+	struct avtab_extended_perms *partial = NULL;
+	struct avtab_extended_perms *complete = NULL;
+	int start_new_range;
+
+	avtab_key = (avtab_key_t *)k;
+	xperms = datum;
+	pdb = args;
+
+	avtab_datum.data = 0;
+
+	start_new_range = 1;
+
+	ebitmap_for_each_bit(xperms, node, i) {
+		if (!ebitmap_get_bit(xperms, i)) continue;
+
+		if (start_new_range) {
+			low = i;
+			start_new_range = 0;
+		}
+
+		// continue if the current bit isn't the end of the driver function or the next bit is set
+		if (IOC_FUNC(i) != 0xff && ebitmap_get_bit(xperms, i + 1)) {
+			continue;
+		}
+
+		// if we got here, i is the end of this range (either becuase the func
+		// is 0xff or the next bit isn't set). The next time around we are
+		// going to need a start a new range
+		high = i;
+		start_new_range = 1;
+
+		if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
+			if (!complete) {
+				complete = cil_calloc(1, sizeof(*complete));
+				complete->driver = 0x0;
+				complete->specified = AVTAB_XPERMS_IOCTLDRIVER;
+			}
+
+			__avrule_xperm_setrangebits(IOC_DRIV(low), IOC_DRIV(low), complete);
+		} else {
+			if (partial && partial->driver != IOC_DRIV(low)) {
+				avtab_datum.xperms = partial;
+				rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
+				if (rc != SEPOL_OK) {
+					goto exit;
+				}
+				free(partial);
+				partial = NULL;
+			}
+
+			if (!partial) {
+				partial = cil_calloc(1, sizeof(*partial));
+				partial->driver = IOC_DRIV(low);
+				partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+			}
+
+			__avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial);
+		}
+	}
+
+	if (partial) {
+		avtab_datum.xperms = partial;
+		rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	if (complete) {
+		avtab_datum.xperms = complete;
+		rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	rc = SEPOL_OK;
+
+exit:
+	free(partial);
+	free(complete);
+
+	// hashtab_t does not have a way to free keys or datum since it doesn't
+	// know what they are. We won't need the keys/datum after this function, so
+	// clean them up here.
+	free(avtab_key);
+	ebitmap_destroy(xperms);
+	free(xperms);
+
+	return rc;
+}
+
+int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
+{
+	uint16_t specified;
+	avtab_key_t *avtab_key;
+	ebitmap_t *hashtab_xperms;
+	int rc = SEPOL_ERR;
+
+	switch (kind) {
+	case CIL_AVRULE_ALLOWED:
+		specified = AVTAB_XPERMS_ALLOWED;
+		break;
+	case CIL_AVRULE_AUDITALLOW:
+		specified = AVTAB_XPERMS_AUDITALLOW;
+		break;
+	case CIL_AVRULE_DONTAUDIT:
+		specified = AVTAB_XPERMS_DONTAUDIT;
+		break;
+	default:
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
+	avtab_key = cil_malloc(sizeof(*avtab_key));
+	avtab_key->source_type = src;
+	avtab_key->target_type = tgt;
+	avtab_key->target_class = obj;
+	avtab_key->specified = specified;
+
+	hashtab_xperms = (ebitmap_t *)hashtab_search(h, (hashtab_key_t)avtab_key);
+	if (!hashtab_xperms) {
+		hashtab_xperms = cil_malloc(sizeof(*hashtab_xperms));
+		rc = ebitmap_cpy(hashtab_xperms, xperms);
+		if (rc != SEPOL_OK) {
+			free(avtab_key);
+			goto exit;
+		}
+		rc = hashtab_insert(h, (hashtab_key_t)avtab_key, hashtab_xperms);
+		if (rc != SEPOL_OK) {
+			free(avtab_key);
+			goto exit;
+		}
+	} else {
+		free(avtab_key);
+		rc = ebitmap_union(hashtab_xperms, xperms);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
+int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_permissionx *permx, struct cil_args_binary *args)
+{
+	int rc = SEPOL_ERR;
+	type_datum_t *sepol_src = NULL;
+	type_datum_t *sepol_tgt = NULL;
+	class_datum_t *sepol_obj = NULL;
+	struct cil_list *class_list = NULL;
+	struct cil_list_item *c;
+
+	rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
+	if (rc != SEPOL_OK) goto exit;
+
+	rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
+	if (rc != SEPOL_OK) goto exit;
+
+	class_list = cil_expand_class(permx->obj);
+
+	cil_list_for_each(c, class_list) {
+		rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
+		if (rc != SEPOL_OK) goto exit;
+
+		switch (permx->kind) {
+		case  CIL_PERMX_KIND_IOCTL:
+			rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
+			if (rc != SEPOL_OK) goto exit;
+			break;
+		default:
+			rc = SEPOL_ERR;
+			goto exit;
+		}
+	}
+
+	rc = SEPOL_OK;
+
+exit:
+	cil_list_destroy(&class_list, CIL_FALSE);
+
+	return rc;
+}
+
+int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrulex *cil_avrulex, struct cil_args_binary *args)
+{
+	int rc = SEPOL_ERR;
+	uint16_t kind;
+	struct cil_symtab_datum *src = NULL;
+	struct cil_symtab_datum *tgt = NULL;
+	ebitmap_t type_bitmap;
+	ebitmap_node_t *tnode;
+	unsigned int i;
+
+	ebitmap_init(&type_bitmap);
+
+	if (cil_avrulex->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
+		// Do not add dontaudit rules to binary
+		rc = SEPOL_OK;
+		goto exit;
+	}
+
+	kind = cil_avrulex->rule_kind;
+	src = cil_avrulex->src;
+	tgt = cil_avrulex->tgt;
+
+	if (tgt->fqn == CIL_KEY_SELF) {
+		rc = __cil_expand_type(src, &type_bitmap);
+		if (rc != SEPOL_OK) goto exit;
+
+		ebitmap_for_each_bit(&type_bitmap, tnode, i) {
+			if (!ebitmap_get_bit(&type_bitmap, i)) continue;
+
+			src = DATUM(db->val_to_type[i]);
+			rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->permx, args);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+		}
+	} else {
+		rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->permx, args);
+		if (rc != SEPOL_OK) goto exit;
+	}
+
+	rc = SEPOL_OK;
+
+exit:
+	ebitmap_destroy(&type_bitmap);
+
+	return rc;
 }
 
 int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
@@ -1593,7 +1799,7 @@
 		break;
 	case CIL_AVRULE:
 		cil_avrule = node->data;
-		rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, args->neverallows, cond_node, cond_flavor);
+		rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path);
 			goto exit;
@@ -1762,7 +1968,7 @@
 	return SEPOL_OK;
 }
 
-int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table)
+int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table)
 {
 	int rc = SEPOL_ERR;
 	struct cil_args_booleanif bool_args;
@@ -1837,7 +2043,6 @@
 	bool_args.db = db;
 	bool_args.pdb = pdb;
 	bool_args.cond_node = cond_node;
-	bool_args.neverallows = neverallows;
 	bool_args.filename_trans_table = filename_trans_table;
 
 	if (true_node != NULL) {
@@ -2004,12 +2209,30 @@
 
 	if (expr_flavor == CIL_USER) {
 		user_datum_t *sepol_user = NULL;
-		rc = __cil_get_sepol_user_datum(pdb, item->data, &sepol_user);
+		ebitmap_t user_bitmap;
+		ebitmap_node_t *unode;
+		unsigned int i;
+
+		rc = __cil_expand_user(item->data, &user_bitmap);
 		if (rc != SEPOL_OK) goto exit;
 
-		if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
-			goto exit;
+		ebitmap_for_each_bit(&user_bitmap, unode, i) {
+			if (!ebitmap_get_bit(&user_bitmap, i)) {
+				continue;
+			}
+
+			rc = __cil_get_sepol_user_datum(pdb, DATUM(db->val_to_user[i]), &sepol_user);
+			if (rc != SEPOL_OK) {
+				ebitmap_destroy(&user_bitmap);
+				goto exit;
+			}
+
+			if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
+				ebitmap_destroy(&user_bitmap);
+				goto exit;
+			}
 		}
+		ebitmap_destroy(&user_bitmap);
 	} else if (expr_flavor == CIL_ROLE) {
 		role_datum_t *sepol_role = NULL;
 		ebitmap_t role_bitmap;
@@ -3115,12 +3338,15 @@
 	hashtab_t filename_trans_table;
 	hashtab_t range_trans_table;
 	hashtab_t role_trans_table;
+	void **type_value_to_cil;
+
 	db = args->db;
 	pdb = args->pdb;
 	pass = args->pass;
 	filename_trans_table = args->filename_trans_table;
 	range_trans_table = args->range_trans_table;
 	role_trans_table = args->role_trans_table;
+	type_value_to_cil = args->type_value_to_cil;
 
 	if (node->flavor >= CIL_MIN_DECLARATIVE) {
 		if (node != DATUM(node->data)->nodes->head->data) {
@@ -3135,10 +3361,10 @@
 			rc = cil_role_to_policydb(pdb, node->data);
 			break;
 		case CIL_TYPE:
-			rc = cil_type_to_policydb(pdb, node->data);
+			rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil);
 			break;
 		case CIL_TYPEATTRIBUTE:
-			rc = cil_typeattribute_to_policydb(pdb, node->data);
+			rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil);
 			break;
 		case CIL_POLICYCAP:
 			rc = cil_policycap_to_policydb(pdb, node->data);
@@ -3192,9 +3418,10 @@
 			if (rc != SEPOL_OK) goto exit;
 			if (pdb->mls == CIL_TRUE) {
 				rc = cil_userlevel_userrange_to_policydb(pdb, node->data);
+				if (rc != SEPOL_OK) {
+					goto exit;
+				}
 			}
-			break;
-		case CIL_USERROLE:
 			rc = cil_userrole_to_policydb(pdb, db, node->data);
 			break;
 		case CIL_TYPE_RULE:
@@ -3202,17 +3429,9 @@
 			break;
 		case CIL_AVRULE: {
 			struct cil_avrule *rule = node->data;
-			struct cil_list *neverallows = args->neverallows;
-			if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
-				struct cil_neverallow *new_rule = NULL;
-
-				new_rule = cil_malloc(sizeof(*new_rule));
-				cil_list_init(&new_rule->rules, CIL_LIST_ITEM);
-				new_rule->node = node;
-
-				cil_list_prepend(neverallows, CIL_LIST_ITEM, new_rule);
-
-				rc = cil_avrule_to_policydb(pdb, db, node->data, neverallows);
+			if (db->disable_neverallow != CIL_TRUE && rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
+				struct cil_list *neverallows = args->neverallows;
+				cil_list_prepend(neverallows, CIL_LIST_ITEM, node);
 			}
 			break;
 		}
@@ -3261,15 +3480,18 @@
 	case 3:
 		switch (node->flavor) {
 		case CIL_BOOLEANIF:
-			rc = cil_booleanif_to_policydb(pdb, db, node, args->neverallows, filename_trans_table);
+			rc = cil_booleanif_to_policydb(pdb, db, node, filename_trans_table);
 			break;
 		case CIL_AVRULE: {
 				struct cil_avrule *rule = node->data;
 				if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
-					rc = cil_avrule_to_policydb(pdb, db, node->data, args->neverallows);
+					rc = cil_avrule_to_policydb(pdb, db, node->data);
 				}
 			}
 			break;
+		case CIL_AVRULEX:
+			rc = cil_avrulex_to_hashtable(pdb, db, node->data, args);
+			break;
 		case CIL_ROLEALLOW:
 			rc = cil_roleallow_to_policydb(pdb, db, node->data);
 			break;
@@ -3608,7 +3830,7 @@
 }
 
 
-int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db)
+int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 
@@ -3618,7 +3840,7 @@
 	pdb->handle_unknown = db->handle_unknown;
 	pdb->mls = db->mls;
 
-	rc = cil_classorder_to_policydb(pdb, db);
+	rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3703,6 +3925,58 @@
 	return a->role != b->role || a->type != b->type || a->tclass != b->tclass;
 }
 
+/* Based on MurmurHash3, written by Austin Appleby and placed in the
+ * public domain.
+ */
+static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, hashtab_key_t key)
+{
+	avtab_key_t *k = (avtab_key_t *)key;
+
+	static const uint32_t c1 = 0xcc9e2d51;
+	static const uint32_t c2 = 0x1b873593;
+	static const uint32_t r1 = 15;
+	static const uint32_t r2 = 13;
+	static const uint32_t m  = 5;
+	static const uint32_t n  = 0xe6546b64;
+
+	uint32_t hash = 0;
+
+#define mix(input) { \
+	uint32_t v = input; \
+	v *= c1; \
+	v = (v << r1) | (v >> (32 - r1)); \
+	v *= c2; \
+	hash ^= v; \
+	hash = (hash << r2) | (hash >> (32 - r2)); \
+	hash = hash * m + n; \
+}
+
+	mix(k->target_class);
+	mix(k->target_type);
+	mix(k->source_type);
+	mix(k->specified);
+
+#undef mix
+
+	hash ^= hash >> 16;
+	hash *= 0x85ebca6b;
+	hash ^= hash >> 13;
+	hash *= 0xc2b2ae35;
+	hash ^= hash >> 16;
+
+	return hash & (AVRULEX_TABLE_SIZE - 1);
+}
+
+static int avrulex_compare(hashtab_t h
+             __attribute__ ((unused)), hashtab_key_t key1,
+			              hashtab_key_t key2)
+{
+	avtab_key_t *a = (avtab_key_t *)key1;
+	avtab_key_t *b = (avtab_key_t *)key2;
+
+	return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class || a->specified != b->specified;
+}
+
 int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb)
 {
 	int rc = SEPOL_ERR;
@@ -3728,6 +4002,413 @@
 	return rc;
 }
 
+static void __cil_destroy_sepol_class_perms(class_perm_node_t *curr)
+{
+	class_perm_node_t *next;
+
+	while (curr) {
+		next = curr->next;
+		free(curr);
+		curr = next;
+	}
+}
+
+static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *classperms, class_perm_node_t **sepol_class_perms)
+{
+	int rc = SEPOL_ERR;
+	struct cil_list_item *i;
+	cil_list_for_each(i, classperms) {
+		if (i->flavor == CIL_CLASSPERMS) {
+			struct cil_classperms *cp = i->data;
+			if (FLAVOR(cp->class) == CIL_CLASS) {
+				class_perm_node_t *cpn = NULL;
+				class_datum_t *sepol_class = NULL;
+				uint32_t data = 0;
+
+				rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
+				if (rc != SEPOL_OK) goto exit;
+
+				rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
+				if (rc != SEPOL_OK) goto exit;
+				if (data == 0) {
+					/* No permissions */
+					return SEPOL_OK;
+				}
+				cpn = cil_malloc(sizeof(class_perm_node_t));
+				cpn->tclass = sepol_class->s.value;
+				cpn->data = data;
+				cpn->next = *sepol_class_perms;
+				*sepol_class_perms = cpn;
+			} else { /* MAP */
+				struct cil_list_item *j = NULL;
+				cil_list_for_each(j, cp->perms) {
+					struct cil_perm *cmp = j->data;
+					rc = __cil_rule_to_sepol_class_perms(pdb, cmp->classperms, sepol_class_perms);
+					if (rc != SEPOL_OK) {
+						goto exit;
+					}
+				}
+			}
+		} else { /* SET */
+			struct cil_classperms_set *cp_set = i->data;
+			struct cil_classpermission *cp = cp_set->set;
+			rc = __cil_rule_to_sepol_class_perms(pdb, cp->classperms, sepol_class_perms);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+		}
+	}
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
+static void __cil_init_sepol_type_set(type_set_t *t)
+{
+	ebitmap_init(&t->types);
+	ebitmap_init(&t->negset);
+	t->flags = 0;
+}
+
+static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map)
+{
+	int rc = SEPOL_ERR;
+	struct cil_tree_node *n = datum->nodes->head->data;
+	type_datum_t *sepol_datum = NULL;
+
+	if (n->flavor == CIL_TYPEATTRIBUTE) {
+		ebitmap_node_t *tnode;
+		unsigned int i;
+		struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
+		ebitmap_for_each_bit(attr->types, tnode, i) {
+			if (!ebitmap_get_bit(attr->types, i)) continue;
+			datum = DATUM(db->val_to_type[i]);
+			rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
+			if (rc != SEPOL_OK) goto exit;
+			ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
+		}
+	} else {
+		rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
+		if (rc != SEPOL_OK) goto exit;
+		ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
+static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node)
+{
+	avrule_t *avrule;
+
+	avrule = cil_malloc(sizeof(avrule_t));
+	avrule->specified = kind;
+	avrule->flags = 0;
+	__cil_init_sepol_type_set(&avrule->stypes);
+	__cil_init_sepol_type_set(&avrule->ttypes);
+	avrule->perms = NULL;
+	avrule->line = node->line;
+	avrule->source_filename = node->path;
+	avrule->source_line = node->line;
+	avrule->next = NULL;
+	return avrule;
+}
+
+static void __cil_destroy_sepol_avrules(avrule_t *curr)
+{
+	avrule_t *next;
+
+	while (curr) {
+		next = curr->next;
+		ebitmap_destroy(&curr->stypes.types);
+		ebitmap_destroy(&curr->stypes.negset);
+		ebitmap_destroy(&curr->ttypes.types);
+		ebitmap_destroy(&curr->ttypes.negset);
+		__cil_destroy_sepol_class_perms(curr->perms);
+		free(curr);
+		curr = next;
+	}
+}
+
+static int __cil_rule_to_expanded_sepol_avrule(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, avrule_t **avrule)
+{
+	int rc = SEPOL_ERR;
+	struct cil_avrule *cil_rule = node->data;
+	struct cil_symtab_datum *tgt = cil_rule->tgt;
+	uint32_t kind;
+	avrule_t *rule;
+
+	*avrule = NULL;
+
+	switch (cil_rule->rule_kind) {
+	case CIL_AVRULE_AUDITALLOW:
+		kind = AVRULE_AUDITALLOW;
+		break;
+	case CIL_AVRULE_DONTAUDIT:
+		kind = AVRULE_AUDITDENY;
+		break;
+	case CIL_AVRULE_NEVERALLOW:
+		kind = AVRULE_NEVERALLOW;
+		break;
+	default:
+		kind = AVRULE_ALLOWED;
+		break;
+	}
+
+	rule = __cil_init_sepol_avrule(kind, node);
+
+	rc = __cil_rule_to_sepol_class_perms(pdb, cil_rule->classperms, &rule->perms);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->stypes.types);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	if (tgt->fqn == CIL_KEY_SELF) {
+		rule->flags = RULE_SELF;
+	} else {
+		rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	rule->next = NULL;
+	*avrule = rule;
+
+	return SEPOL_OK;
+
+exit:
+	__cil_destroy_sepol_avrules(rule);
+	return rc;
+}
+
+static void __cil_print_parents(const char *pad, struct cil_tree_node *n)
+{
+	if (!n) return;
+
+	__cil_print_parents(pad, n->parent);
+
+	if (!n->path) {
+		cil_log(CIL_ERR,"%s%s\n", pad, cil_node_to_string(n));
+	} else {
+		cil_log(CIL_ERR,"%s%s at line %d of %s\n", pad, cil_node_to_string(n), n->line, n->path);
+	}
+}
+
+static void __cil_print_rule(const char *pad, const char *kind, struct cil_avrule *avrule)
+{
+	struct cil_list *cp_list = avrule->classperms;
+	struct cil_list_item *i1, *i2;
+
+	cil_log(CIL_ERR,"%s(%s ", pad, kind);
+	cil_log(CIL_ERR,"%s %s ", DATUM(avrule->src)->fqn, DATUM(avrule->tgt)->fqn);
+
+	i1 = cp_list->head;
+	if (i1->flavor == CIL_CLASSPERMS) {
+		struct cil_classperms *cp = i1->data;
+		cil_log(CIL_ERR,"(%s (", DATUM(cp->class)->fqn);
+		cil_list_for_each(i2, cp->perms) {
+			cil_log(CIL_ERR,"%s",DATUM(i2->data)->fqn);
+			if (i2 != cp->perms->tail) {
+				cil_log(CIL_ERR," ");
+			} else {
+				cil_log(CIL_ERR,"))");
+			}
+		}
+	} else {
+		struct cil_classperms_set *cp_set = i1->data;
+		cil_log(CIL_ERR,"%s", DATUM(cp_set->set)->fqn);
+	}
+
+	cil_log(CIL_ERR,")\n");
+}
+
+static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows)
+{
+	int rc = SEPOL_OK;
+	struct cil_list_item *i1;
+
+	cil_list_for_each(i1, neverallows) {
+		struct cil_tree_node *node = i1->data;
+		avrule_t *avrule;
+		rc = __cil_rule_to_expanded_sepol_avrule(db, pdb, node, &avrule);
+		if (rc != SEPOL_OK) {
+			cil_log(CIL_ERR, "Failed to create expanded sepol avrules to check neverallow rules\n");
+			goto exit;
+		}
+
+		rc = check_assertion(pdb, avrule);
+
+		if (rc == CIL_TRUE) {
+			struct cil_list_item *i2;
+			struct cil_list *matching;
+			struct cil_avrule *cil_rule = node->data;
+			struct cil_avrule target;
+			struct cil_tree_node *n2;
+			struct cil_avrule *r2;
+			target.rule_kind = CIL_AVRULE_ALLOWED;
+			target.src = cil_rule->src;
+			target.tgt = cil_rule->tgt;
+			target.classperms = cil_rule->classperms;
+			cil_log(CIL_ERR, "Neverallow check failed at line %d of %s\n", node->line, node->path);
+			__cil_print_rule("  ", "neverallow", cil_rule);
+			cil_list_init(&matching, CIL_NODE);
+			rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE);
+			if (rc) {
+				cil_log(CIL_ERR, "Error occurred while checking neverallow rules\n");
+				cil_list_destroy(&matching, CIL_FALSE);
+				__cil_destroy_sepol_avrules(avrule);
+				goto exit;
+			}
+
+			cil_list_for_each(i2, matching) {
+				n2 = i2->data;
+				r2 = n2->data;
+				__cil_print_parents("    ", n2);
+				__cil_print_rule("      ", "allow", r2);
+			}
+			cil_log(CIL_ERR,"\n");
+			cil_list_destroy(&matching, CIL_FALSE);
+		}
+		__cil_destroy_sepol_avrules(avrule);
+		avrule = NULL;
+	}
+
+exit:
+	return rc;
+}
+
+static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
+{
+	struct cil_classperms *cp;
+	struct cil_list *cp_list;
+	class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1];
+	unsigned i;
+
+	cil_classperms_init(&cp);
+
+	cp->class = class_value_to_cil[class];
+	if (!cp->class) goto exit;
+
+	cil_list_init(&cp->perms, CIL_PERM);
+	for (i = 0; i < sepol_class->permissions.nprim; i++) {
+		struct cil_perm *perm;
+		if ((data & (1 << i)) == 0) continue;
+		perm = perm_value_to_cil[class][i+1];
+		if (!perm) goto exit;
+		cil_list_append(cp->perms, CIL_PERM, perm);
+	}
+
+	cil_list_init(&cp_list, CIL_CLASSPERMS);
+	cil_list_append(cp_list, CIL_CLASSPERMS, cp);
+
+	return cp_list;
+
+exit:
+	cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n");
+	return NULL;
+}
+
+static int cil_avrule_from_sepol(policydb_t *pdb, avtab_ptr_t sepol_rule, struct cil_avrule *cil_rule, void *type_value_to_cil[], struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
+{
+	int rc = SEPOL_ERR;
+	avtab_key_t *k = &sepol_rule->key;
+	avtab_datum_t *d = &sepol_rule->datum;
+	cil_rule->src = type_value_to_cil[k->source_type];
+	if (!cil_rule->src) goto exit;
+
+	cil_rule->tgt = type_value_to_cil[k->target_type];
+	if (!cil_rule->tgt) goto exit;
+
+	cil_rule->classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil);
+	if (!cil_rule->classperms) goto exit;
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n");
+	return rc;
+}
+
+static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
+{
+	int rc = SEPOL_OK;
+	int i;
+
+	for (i = 0; i < db->num_types; i++) {
+		type_datum_t *child;
+		type_datum_t *parent;
+		avtab_ptr_t bad = NULL;
+		int numbad = 0;
+		struct cil_type *t = db->val_to_type[i];
+
+		if (!t->bounds) continue;
+
+		rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child);
+		if (rc != SEPOL_OK) goto exit;
+
+		rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent);
+		if (rc != SEPOL_OK) goto exit;
+
+		rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad);
+		if (rc != SEPOL_OK) goto exit;
+
+		if (bad) {
+			avtab_ptr_t cur;
+			struct cil_avrule target;
+
+			target.rule_kind = CIL_AVRULE_ALLOWED;
+			target.src_str = NULL;
+			target.tgt_str = NULL;
+
+			cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n",
+				t->datum.fqn, t->bounds->datum.fqn);
+			for (cur = bad; cur; cur = cur->next) {
+				struct cil_list_item *i2;
+				struct cil_list *matching;
+				struct cil_tree_node *n;
+
+				rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
+				if (rc != SEPOL_OK) {
+					cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n");
+					goto exit;
+				}
+				__cil_print_rule("  ", "allow", &target);
+				cil_list_init(&matching, CIL_NODE);
+				rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE);
+				if (rc) {
+					cil_log(CIL_ERR, "Error occurred while checking type bounds\n");
+					cil_list_destroy(&matching, CIL_FALSE);
+					cil_list_destroy(&target.classperms, CIL_TRUE);
+					bounds_destroy_bad(bad);
+					goto exit;
+				}
+
+				cil_list_for_each(i2, matching) {
+					__cil_print_parents("    ", (struct cil_tree_node *)i2->data);
+				}
+				i2 = matching->tail;
+				n = i2->data;
+				__cil_print_rule("      ", "allow", n->data);
+				cil_log(CIL_ERR,"\n");
+				cil_list_destroy(&matching, CIL_FALSE);
+				cil_list_destroy(&target.classperms, CIL_TRUE);
+			}
+			bounds_destroy_bad(bad);
+		}
+	}
+
+exit:
+	return rc;
+}
+
 // assumes policydb is already allocated and initialized properly with things
 // like policy type set to kernel and version set appropriately
 int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb)
@@ -3740,6 +4421,10 @@
 	hashtab_t filename_trans_table = NULL;
 	hashtab_t range_trans_table = NULL;
 	hashtab_t role_trans_table = NULL;
+	hashtab_t avrulex_ioctl_table = NULL;
+	void **type_value_to_cil = NULL;
+	struct cil_class **class_value_to_cil = NULL;
+	struct cil_perm ***perm_value_to_cil = NULL;
 
 	if (db == NULL || policydb == NULL) {
 		if (db == NULL) {
@@ -3750,7 +4435,23 @@
 		return SEPOL_ERR;
 	}
 
-	rc = __cil_policydb_init(pdb, db);
+	/* libsepol values start at 1. Just allocate extra memory rather than
+	 * subtract 1 from the sepol value.
+	 */
+	type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil));
+	if (!type_value_to_cil) goto exit;
+
+	class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil));
+	if (!class_value_to_cil) goto exit;
+
+	perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil));
+	if (!perm_value_to_cil) goto exit;
+	for (i=1; i < db->num_classes+1; i++) {
+		perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i]));
+		if (!perm_value_to_cil[i]) goto exit;
+	}
+
+	rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil);
 	if (rc != SEPOL_OK) {
 		cil_log(CIL_ERR,"Problem in policydb_init\n");
 		goto exit;
@@ -3774,6 +4475,12 @@
 		goto exit;
 	}
 
+	avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE);
+	if (!avrulex_ioctl_table) {
+		cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n");
+		goto exit;
+	}
+
 	cil_list_init(&neverallows, CIL_LIST_ITEM);
 
 	extra_args.db = db;
@@ -3782,6 +4489,9 @@
 	extra_args.filename_trans_table = filename_trans_table;
 	extra_args.range_trans_table = range_trans_table;
 	extra_args.role_trans_table = role_trans_table;
+	extra_args.avrulex_ioctl_table = avrulex_ioctl_table;
+	extra_args.type_value_to_cil = type_value_to_cil;
+
 	for (i = 1; i <= 3; i++) {
 		extra_args.pass = i;
 
@@ -3798,6 +4508,14 @@
 				goto exit;
 			}
 		}
+
+		if (i == 3) {
+			rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb);
+			if (rc != SEPOL_OK) {
+				cil_log(CIL_INFO, "Failure creating avrulex rules\n");
+				goto exit;
+			}
+		}
 	}
 
 	rc = cil_sidorder_to_policydb(pdb, db);
@@ -3822,13 +4540,38 @@
 	cond_optimize_lists(pdb->cond_list);
 	__cil_set_conditional_state_and_flags(pdb);
 
+	if (db->disable_neverallow != CIL_TRUE) {
+		cil_log(CIL_INFO, "Checking Neverallows\n");
+		rc = cil_check_neverallows(db, pdb, neverallows);
+		if (rc != SEPOL_OK) goto exit;
+
+		cil_log(CIL_INFO, "Checking User Bounds\n");
+		bounds_check_users(NULL, pdb);
+
+		cil_log(CIL_INFO, "Checking Role Bounds\n");
+		bounds_check_roles(NULL, pdb);
+
+		cil_log(CIL_INFO, "Checking Type Bounds\n");
+		rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
+		if (rc != SEPOL_OK) goto exit;
+
+	}
+
 	rc = SEPOL_OK;
 
 exit:
 	hashtab_destroy(filename_trans_table);
 	hashtab_destroy(range_trans_table);
 	hashtab_destroy(role_trans_table);
-	cil_neverallows_list_destroy(neverallows);
+	hashtab_destroy(avrulex_ioctl_table);
+	free(type_value_to_cil);
+	free(class_value_to_cil);
+	/* Range is because libsepol values start at 1. */
+	for (i=1; i < db->num_classes+1; i++) {
+		free(perm_value_to_cil[i]);
+	}
+	free(perm_value_to_cil);
+	cil_list_destroy(&neverallows, CIL_FALSE);
 
 	return rc;
 }
diff --git a/libsepol/cil/src/cil_binary.h b/libsepol/cil/src/cil_binary.h
index 5045c6e..c59b1e3 100644
--- a/libsepol/cil/src/cil_binary.h
+++ b/libsepol/cil/src/cil_binary.h
@@ -112,7 +112,7 @@
  *
  * @return SEPOL_OK upon success or an error otherwise.
  */
-int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type);
+int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[]);
 
 /**
  * Insert cil typealias structure into sepol policydb.
@@ -144,7 +144,7 @@
  *
  * @return SEPOL_OK upon success or an error otherwise.
  */
-int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr);
+int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[]);
 
 /**
  * Insert cil attribute structure into sepol type->attribute bitmap.
@@ -184,12 +184,13 @@
 /**
  * Insert cil userrole structure into sepol policydb.
  *
- * @param[in] pdb THe policy database to insert the userrole into.
- * @param[in] datum The cil_userrole datum.
+ * @param[in] pdb The policy database to insert the userrole into.
+ * @param[in] db The cil database
+ * @param[in] datum The cil_user
  *
  * @return SEPOL_OK upon success or SEPOL_ERR otherwise.
  */
-int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole);
+int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user);
 
 /**
  * Insert cil bool structure into sepol policydb.
@@ -250,7 +251,7 @@
  *
  * @return SEPOL_OK upon success or an error otherwise.
  */
-int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows);
+int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule);
 
 /**
  * Insert cil booleanif structure into sepol policydb.  This populates the
@@ -262,7 +263,7 @@
  *
  * @return SEPOL_OK upon success or an error otherwise.
  */
-int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table);
+int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table);
 
 /**
  * Insert cil role transition structure into sepol policydb.
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 92c3e09..861b606 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -1196,10 +1196,132 @@
 	}
 
 	cil_symtab_datum_destroy(&user->datum);
-	cil_list_destroy(&user->roles, CIL_FALSE);
+	ebitmap_destroy(user->roles);
+	free(user->roles);
 	free(user);
 }
 
+int cil_gen_userattribute(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_END
+	};
+	int syntax_len = sizeof(syntax)/sizeof(*syntax);
+	char *key = NULL;
+	struct cil_userattribute *attr = NULL;
+	int rc = SEPOL_ERR;
+
+	if (parse_current == NULL || ast_node == NULL) {
+		goto exit;
+	}
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_userattribute_init(&attr);
+
+	key = parse_current->next->data;
+	rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)attr, (hashtab_key_t)key, CIL_SYM_USERS, CIL_USERATTRIBUTE);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	return SEPOL_OK;
+exit:
+	cil_log(CIL_ERR, "Bad userattribute declaration at line %d of %s\n",
+		parse_current->line, parse_current->path);
+	cil_destroy_userattribute(attr);
+	cil_clear_node(ast_node);
+	return rc;
+}
+
+void cil_destroy_userattribute(struct cil_userattribute *attr)
+{
+	struct cil_list_item *expr = NULL;
+	struct cil_list_item *next = NULL;
+
+	if (attr == NULL) {
+		return;
+	}
+
+	if (attr->expr_list != NULL) {
+		/* we don't want to destroy the expression stacks (cil_list) inside
+		 * this list cil_list_destroy destroys sublists, so we need to do it
+		 * manually */
+		expr = attr->expr_list->head;
+		while (expr != NULL) {
+			next = expr->next;
+			cil_list_item_destroy(&expr, CIL_FALSE);
+			expr = next;
+		}
+		free(attr->expr_list);
+		attr->expr_list = NULL;
+	}
+
+	cil_symtab_datum_destroy(&attr->datum);
+	ebitmap_destroy(attr->users);
+	free(attr->users);
+	free(attr);
+}
+
+int cil_gen_userattributeset(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_STRING | CIL_SYN_LIST,
+		CIL_SYN_END
+	};
+	int syntax_len = sizeof(syntax)/sizeof(*syntax);
+	struct cil_userattributeset *attrset = NULL;
+	int rc = SEPOL_ERR;
+
+	if (db == NULL || parse_current == NULL || ast_node == NULL) {
+		goto exit;
+	}
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_userattributeset_init(&attrset);
+
+	attrset->attr_str = parse_current->next->data;
+
+	rc = cil_gen_expr(parse_current->next->next, CIL_USER, &attrset->str_expr);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+	ast_node->data = attrset;
+	ast_node->flavor = CIL_USERATTRIBUTESET;
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Bad userattributeset declaration at line %d of %s\n",
+		parse_current->line, parse_current->path);
+	cil_destroy_userattributeset(attrset);
+
+	return rc;
+}
+
+void cil_destroy_userattributeset(struct cil_userattributeset *attrset)
+{
+	if (attrset == NULL) {
+		return;
+	}
+
+	cil_list_destroy(&attrset->str_expr, CIL_TRUE);
+	cil_list_destroy(&attrset->datum_expr, CIL_FALSE);
+
+	free(attrset);
+}
+
 int cil_gen_userlevel(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
 {
 	enum cil_syntax syntax[] = {
@@ -1903,6 +2025,169 @@
 	free(rule);
 }
 
+int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permissionx *permx)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_LIST,
+		CIL_SYN_END
+	};
+	int syntax_len = sizeof(syntax)/sizeof(*syntax);
+	int rc = SEPOL_ERR;
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	if (parse_current->data == CIL_KEY_IOCTL) {
+		permx->kind = CIL_PERMX_KIND_IOCTL;
+	} else {
+		cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\"\n", (char *)parse_current->data);
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
+	permx->obj_str = parse_current->next->data;
+
+	rc = cil_gen_expr(parse_current->next->next, CIL_PERMISSIONX, &permx->expr_str);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Bad permissionx content at line %d of %s\n",
+		parse_current->line, parse_current->path);
+	return rc;
+}
+
+int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_LIST,
+		CIL_SYN_END
+	};
+	int syntax_len = sizeof(syntax)/sizeof(*syntax);
+	char *key = NULL;
+	struct cil_permissionx *permx = NULL;
+	int rc = SEPOL_ERR;
+
+	if (parse_current == NULL || ast_node == NULL) {
+		goto exit;
+	}
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_permissionx_init(&permx);
+
+	key = parse_current->next->data;
+
+	rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)permx, (hashtab_key_t)key, CIL_SYM_PERMX, CIL_PERMISSIONX);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	rc = cil_fill_permissionx(parse_current->next->next->cl_head, permx);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Bad permissionx statement at line %d of %s\n",
+		parse_current->line, parse_current->path);
+	cil_destroy_permissionx(permx);
+	cil_clear_node(ast_node);
+	return rc;
+}
+
+void cil_destroy_permissionx(struct cil_permissionx *permx)
+{
+	if (permx == NULL) {
+		return;
+	}
+
+	cil_symtab_datum_destroy(&permx->datum);
+
+	cil_list_destroy(&permx->expr_str, CIL_TRUE);
+	ebitmap_destroy(permx->perms);
+	free(permx->perms);
+	free(permx);
+}
+
+int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_STRING,
+		CIL_SYN_STRING | CIL_SYN_LIST,
+		CIL_SYN_END
+	};
+	int syntax_len = sizeof(syntax)/sizeof(*syntax);
+	struct cil_avrulex *rule = NULL;
+	int rc = SEPOL_ERR;
+
+	if (parse_current == NULL || ast_node == NULL) {
+		goto exit;
+	}
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_avrulex_init(&rule);
+
+	rule->rule_kind = rule_kind;
+	rule->src_str = parse_current->next->data;
+	rule->tgt_str = parse_current->next->next->data;
+
+	if (parse_current->next->next->next->cl_head == NULL) {
+		rule->permx_str = parse_current->next->next->next->data;
+	} else {
+		cil_permissionx_init(&rule->permx);
+
+		rc = cil_fill_permissionx(parse_current->next->next->next->cl_head, rule->permx);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	ast_node->data = rule;
+	ast_node->flavor = CIL_AVRULEX;
+
+	return SEPOL_OK;
+
+exit:
+	cil_log(CIL_ERR, "Bad allowx rule at line %d of %s\n",
+		parse_current->line, parse_current->path);
+	cil_destroy_avrulex(rule);
+	return rc;
+}
+
+void cil_destroy_avrulex(struct cil_avrulex *rule)
+{
+	if (rule == NULL) {
+		return;
+	}
+
+	if (rule->permx_str == NULL && rule->permx != NULL) {
+		cil_destroy_permissionx(rule->permx);
+	}
+
+	free(rule);
+}
+
 int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind)
 {
 	enum cil_syntax syntax[] = {
@@ -2217,8 +2502,8 @@
 	else if (op == CIL_KEY_EQ)    return CIL_EQ;    /* Only conditional */
 	else if (op == CIL_KEY_NEQ)   return CIL_NEQ;   /* Only conditional */
 	else if (op == CIL_KEY_XOR)   return CIL_XOR;
-	else if (op == CIL_KEY_ALL)   return CIL_ALL;   /* Only set */
-	else if (op == CIL_KEY_RANGE) return CIL_RANGE; /* Only catset */
+	else if (op == CIL_KEY_ALL)   return CIL_ALL;   /* Only set and permissionx */
+	else if (op == CIL_KEY_RANGE) return CIL_RANGE; /* Only catset and permissionx */
 	else return CIL_NONE;
 }
 
@@ -5587,27 +5872,14 @@
 	}
 
 	if (macro != NULL) {
-		if (parse_current->data == CIL_KEY_MACRO) {
+		if (parse_current->data == CIL_KEY_MACRO ||
+			parse_current->data == CIL_KEY_TUNABLE ||
+			parse_current->data == CIL_KEY_IN ||
+			parse_current->data == CIL_KEY_BLOCK ||
+			parse_current->data == CIL_KEY_BLOCKINHERIT ||
+			parse_current->data == CIL_KEY_BLOCKABSTRACT) {
 			rc = SEPOL_ERR;
-			cil_log(CIL_ERR, "Found macro at line %d of %s\n",
-				parse_current->line, parse_current->path);
-			cil_log(CIL_ERR, "Macros cannot be defined within macro statement\n");
-			goto exit;
-		}
-
-		if (parse_current->data == CIL_KEY_TUNABLE) {
-			rc = SEPOL_ERR;
-			cil_log(CIL_ERR, "Found tunable at line %d of %s\n",
-				parse_current->line, parse_current->path);
-			cil_log(CIL_ERR, "Tunables cannot be defined within macro statement\n");
-			goto exit;
-		}
-
-		if (parse_current->data == CIL_KEY_IN) {
-			rc = SEPOL_ERR;
-			cil_log(CIL_ERR, "Found in at line %d of %s\n",
-				parse_current->line, parse_current->path);
-			cil_log(CIL_ERR, "in-statements cannot be defined within macro statement\n");
+			cil_log(CIL_ERR, "%s is not allowed in macros (%s:%d)\n", (char *)parse_current->data, parse_current->path, parse_current->line);
 			goto exit;
 		}
 	}
@@ -5705,6 +5977,11 @@
 		*finished = CIL_TREE_SKIP_NEXT;
 	} else if (parse_current->data == CIL_KEY_USER) {
 		rc = cil_gen_user(db, parse_current, ast_node);
+	} else if (parse_current->data == CIL_KEY_USERATTRIBUTE) {
+		rc = cil_gen_userattribute(db, parse_current, ast_node);
+	} else if (parse_current->data == CIL_KEY_USERATTRIBUTESET) {
+		rc = cil_gen_userattributeset(db, parse_current, ast_node);
+		*finished = CIL_TREE_SKIP_NEXT;
 	} else if (parse_current->data == CIL_KEY_USERLEVEL) {
 		rc = cil_gen_userlevel(db, parse_current, ast_node);
 		*finished = CIL_TREE_SKIP_NEXT;
@@ -5789,6 +6066,18 @@
 	} else if (parse_current->data == CIL_KEY_NEVERALLOW) {
 		rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_NEVERALLOW);
 		*finished = CIL_TREE_SKIP_NEXT;
+	} else if (parse_current->data == CIL_KEY_ALLOWX) {
+		rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_ALLOWED);
+		*finished = CIL_TREE_SKIP_NEXT;
+	} else if (parse_current->data == CIL_KEY_AUDITALLOWX) {
+		rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_AUDITALLOW);
+		*finished = CIL_TREE_SKIP_NEXT;
+	} else if (parse_current->data == CIL_KEY_DONTAUDITX) {
+		rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_DONTAUDIT);
+		*finished = CIL_TREE_SKIP_NEXT;
+	} else if (parse_current->data == CIL_KEY_PERMISSIONX) {
+		rc = cil_gen_permissionx(db, parse_current, ast_node);
+		*finished = CIL_TREE_SKIP_NEXT;
 	} else if (parse_current->data == CIL_KEY_TYPETRANSITION) {
 		rc = cil_gen_typetransition(db, parse_current, ast_node);
 	} else if (parse_current->data == CIL_KEY_TYPECHANGE) {
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 43bc7f6..11f51f5 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -80,6 +80,10 @@
 void cil_destroy_sidorder(struct cil_sidorder *sidorder);
 int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_user(struct cil_user *user);
+int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_userattribute(struct cil_userattribute *attr);
+int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_userattributeset(struct cil_userattributeset *attrset);
 int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_userlevel(struct cil_userlevel *usrlvl);
 int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
@@ -107,6 +111,10 @@
 int cil_gen_rolebounds(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind);
 void cil_destroy_avrule(struct cil_avrule *rule);
+int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind);
+void cil_destroy_avrulex(struct cil_avrulex *rule);
+int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
+void cil_destroy_permissionx(struct cil_permissionx *permx);
 int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint32_t rule_kind);
 void cil_destroy_type_rule(struct cil_type_rule *rule);
 int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index 199ce1c..8c50ff0 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -282,6 +282,8 @@
 		}
 	}
 
+	cil_classpermission_init(&new);
+
 	cil_copy_classperms_list(orig->classperms, &new->classperms);
 
 	*copy = new;
@@ -294,6 +296,8 @@
 	struct cil_classpermissionset *orig = data;
 	struct cil_classpermissionset *new = NULL;
 
+	cil_classpermissionset_init(&new);
+
 	new->set_str = orig->set_str;
 
 	cil_copy_classperms_list(orig->classperms, &new->classperms);
@@ -388,6 +392,41 @@
 	return SEPOL_OK;
 }
 
+int cil_copy_userattribute(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
+{
+	struct cil_userattribute *orig = data;
+	struct cil_userattribute *new = NULL;
+	char *key = orig->datum.name;
+	struct cil_symtab_datum *datum = NULL;
+
+	cil_symtab_get_datum(symtab, key, &datum);
+	if (datum == NULL) {
+		cil_userattribute_init(&new);
+		*copy = new;
+	} else {
+		*copy = datum;
+	}
+
+	return SEPOL_OK;
+}
+
+int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
+{
+	struct cil_userattributeset *orig = data;
+	struct cil_userattributeset *new = NULL;
+
+	cil_userattributeset_init(&new);
+
+	new->attr_str = orig->attr_str;
+
+	cil_copy_expr(db, orig->str_expr, &new->str_expr);
+	cil_copy_expr(db, orig->datum_expr, &new->datum_expr);
+
+	*copy = new;
+
+	return SEPOL_OK;
+}
+
 int cil_copy_userrole(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
 {
 	struct cil_userrole *orig = data;
@@ -760,6 +799,59 @@
 	return SEPOL_OK;
 }
 
+void cil_copy_fill_permissionx(struct cil_db *db, struct cil_permissionx *orig, struct cil_permissionx *new)
+{
+	new->kind = orig->kind;
+	new->obj_str = orig->obj_str;
+	cil_copy_expr(db, orig->expr_str, &new->expr_str);
+}
+
+int cil_copy_permissionx(struct cil_db *db, void *data, void **copy, symtab_t *symtab)
+{
+	struct cil_permissionx *orig = data;
+	struct cil_permissionx *new = NULL;
+	char *key = orig->datum.name;
+	struct cil_symtab_datum *datum = NULL;
+
+
+	cil_symtab_get_datum(symtab, key, &datum);
+	if (datum != NULL) {
+		cil_log(CIL_INFO, "cil_copy_permissionx: permissionx cannot be redefined\n");
+		return SEPOL_ERR;
+	}
+
+	cil_permissionx_init(&new);
+	cil_copy_fill_permissionx(db, orig, new);
+
+	*copy = new;
+
+	return SEPOL_OK;
+}
+
+
+int cil_copy_avrulex(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
+{
+	struct cil_avrulex *orig = data;
+	struct cil_avrulex *new = NULL;
+
+	cil_avrulex_init(&new);
+
+	new->rule_kind = orig->rule_kind;
+	new->src_str = orig->src_str;
+	new->tgt_str = orig->tgt_str;
+
+	if (new->permx_str != NULL) {
+		new->permx_str = orig->permx_str;
+	} else {
+		cil_permissionx_init(&new->permx);
+		cil_copy_fill_permissionx(db, orig->permx, new->permx);
+	}
+
+	*copy = new;
+
+	return SEPOL_OK;
+}
+
 int cil_copy_type_rule(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
 {
 	struct cil_type_rule  *orig = data;
@@ -1660,6 +1752,12 @@
 	case CIL_USER:
 		copy_func = &cil_copy_user;
 		break;
+	case CIL_USERATTRIBUTE:
+		copy_func = &cil_copy_userattribute;
+		break;
+	case CIL_USERATTRIBUTESET:
+		copy_func = &cil_copy_userattributeset;
+		break;
 	case CIL_USERROLE:
 		copy_func = &cil_copy_userrole;
 		break;
@@ -1732,6 +1830,12 @@
 	case CIL_AVRULE:
 		copy_func = &cil_copy_avrule;
 		break;
+	case CIL_AVRULEX:
+		copy_func = &cil_copy_avrulex;
+		break;
+	case CIL_PERMISSIONX:
+		copy_func = &cil_copy_permissionx;
+		break;
 	case CIL_TYPE_RULE:
 		copy_func = &cil_copy_type_rule;
 		break;
@@ -1909,7 +2013,14 @@
 
 		if (new->flavor == CIL_BLOCKINHERIT) {
 			blockinherit = new->data;
-			cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
+			// if a blockinherit statement is copied before blockinherit are
+			// resolved (like in an in-statement), the block will not have been
+			// resolved yet, so there's nothing to append yet. This is fine,
+			// the copied blockinherit statement will be handled later, as if
+			// it wasn't in an in-statement
+			if (blockinherit->block != NULL) {
+				cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
+			}
 		}
 
 		if (parent->cl_head == NULL) {
diff --git a/libsepol/cil/src/cil_copy_ast.h b/libsepol/cil/src/cil_copy_ast.h
index bd3a231..78c34b8 100644
--- a/libsepol/cil/src/cil_copy_ast.h
+++ b/libsepol/cil/src/cil_copy_ast.h
@@ -57,6 +57,8 @@
 int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_sidorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_user(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
+int cil_copy_userattribute(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
+int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_userrole(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_userlevel(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_userrange(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
diff --git a/libsepol/cil/src/cil_find.c b/libsepol/cil/src/cil_find.c
new file mode 100644
index 0000000..a76dc37
--- /dev/null
+++ b/libsepol/cil/src/cil_find.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2011 Tresys Technology, LLC. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``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 TRESYS TECHNOLOGY, LLC 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.
+ *
+ * The views and conclusions contained in the software and documentation are those
+ * of the authors and should not be interpreted as representing official policies,
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
+#include <sepol/policydb/ebitmap.h>
+
+#include "cil_internal.h"
+#include "cil_flavor.h"
+#include "cil_list.h"
+#include "cil_log.h"
+#include "cil_symtab.h"
+
+struct cil_args_find {
+	enum cil_flavor flavor;
+	void *target;
+	struct cil_list *matching;
+	int match_self;
+};
+
+static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
+{
+	enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
+	enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
+
+	if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_type *t1 = (struct cil_type *)d1;
+		struct cil_type *t2 = (struct cil_type *)d2;
+		if (t1->value == t2->value) {
+			return CIL_TRUE;
+		}
+	} else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
+		struct cil_type *t = (struct cil_type *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			return CIL_TRUE;
+		}
+	} else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
+		struct cil_type *t = (struct cil_type *)d1;
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			return CIL_TRUE;
+		}
+	} else {
+		/* Both are attributes */
+		struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
+		struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
+		return ebitmap_match_any(a1->types, a2->types);
+	}
+	return CIL_FALSE;
+}
+
+static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
+{
+	int rc = SEPOL_OK;
+	enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
+	enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
+
+	if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_type *t1 = (struct cil_type *)d1;
+		struct cil_type *t2 = (struct cil_type *)d2;
+		if (t1->value == t2->value) {
+			ebitmap_set_bit(matches, t1->value, 1);
+		}
+	} else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
+		struct cil_type *t = (struct cil_type *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			ebitmap_set_bit(matches, t->value, 1);
+		}
+	} else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
+		struct cil_type *t = (struct cil_type *)d1;
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			ebitmap_set_bit(matches, t->value, 1);
+		}
+	} else {
+		/* Both are attributes */
+		struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
+		struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
+		rc = ebitmap_and(matches, a1->types, a2->types);
+	}
+
+	return rc;
+}
+
+/* s1 is the src type that is matched with a self
+ * s2, and t2 are the source and type of the other rule
+ */
+static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
+{
+	int rc;
+	struct cil_tree_node *n1 = s1->nodes->head->data;
+	if (n1->flavor != CIL_TYPEATTRIBUTE) {
+		rc = cil_type_match_any(s1, t2);
+	} else {
+		struct cil_typeattribute *a = (struct cil_typeattribute *)s1;
+		ebitmap_t map;
+		ebitmap_init(&map);
+		rc = cil_type_matches(&map, s2, t2);
+		if (rc < 0) {
+			ebitmap_destroy(&map);
+			goto exit;
+		}
+		if (map.node == NULL) {
+			rc = CIL_FALSE;
+			goto exit;
+		}
+		rc = ebitmap_match_any(&map, a->types);
+		ebitmap_destroy(&map);
+	}
+
+exit:
+	return rc;
+}
+
+static int cil_classperms_match_any(struct cil_classperms *cp1, struct cil_classperms *cp2)
+{
+	struct cil_class *c1 = cp1->class;
+	struct cil_class *c2 = cp2->class;
+	struct cil_list_item *i1, *i2;
+
+	if (&c1->datum != &c2->datum) return CIL_FALSE;
+
+	cil_list_for_each(i1, cp1->perms) {
+		struct cil_perm *p1 = i1->data;
+		cil_list_for_each(i2, cp2->perms) {
+			struct cil_perm *p2 = i2->data;
+			if (&p1->datum == &p2->datum) return CIL_TRUE;
+		}
+	}
+	return CIL_FALSE;
+}
+
+static int __cil_classperms_list_match_any(struct cil_classperms *cp1, struct cil_list *cpl2)
+{
+	int rc;
+	struct cil_list_item *curr;
+
+	cil_list_for_each(curr, cpl2) {
+		if (curr->flavor == CIL_CLASSPERMS) {
+			struct cil_classperms *cp = curr->data;
+			if (FLAVOR(cp->class) == CIL_CLASS) {
+				rc = cil_classperms_match_any(cp1, cp);
+				if (rc == CIL_TRUE) return CIL_TRUE;
+			} else { /* MAP */
+				struct cil_list_item *i = NULL;
+				cil_list_for_each(i, cp->perms) {
+					struct cil_perm *cmp = i->data;
+					rc = __cil_classperms_list_match_any(cp1, cmp->classperms);
+					if (rc == CIL_TRUE) return CIL_TRUE;
+				}
+			}
+		} else { /* SET */
+			struct cil_classperms_set *cp_set = curr->data;
+			struct cil_classpermission *cp = cp_set->set;
+			rc = __cil_classperms_list_match_any(cp1, cp->classperms);
+			if (rc == CIL_TRUE) return CIL_TRUE;
+		}
+	}
+	return CIL_FALSE;
+}
+
+static int cil_classperms_list_match_any(struct cil_list *cpl1, struct cil_list *cpl2)
+{
+	int rc;
+	struct cil_list_item *curr;
+
+	cil_list_for_each(curr, cpl1) {
+		if (curr->flavor == CIL_CLASSPERMS) {
+			struct cil_classperms *cp = curr->data;
+			if (FLAVOR(cp->class) == CIL_CLASS) {
+				rc = __cil_classperms_list_match_any(cp, cpl2);
+				if (rc == CIL_TRUE) return CIL_TRUE;
+			} else { /* MAP */
+				struct cil_list_item *i = NULL;
+				cil_list_for_each(i, cp->perms) {
+					struct cil_perm *cmp = i->data;
+					rc = cil_classperms_list_match_any(cmp->classperms, cpl2);
+					if (rc == CIL_TRUE) return CIL_TRUE;
+				}
+			}
+		} else { /* SET */
+			struct cil_classperms_set *cp_set = curr->data;
+			struct cil_classpermission *cp = cp_set->set;
+			rc = cil_classperms_list_match_any(cp->classperms, cpl2);
+			if (rc == CIL_TRUE) return CIL_TRUE;
+		}
+	}
+	return CIL_FALSE;
+}
+
+int cil_find_matching_avrule(struct cil_tree_node *node, struct cil_avrule *avrule, struct cil_avrule *target, struct cil_list *matching, int match_self)
+{
+	int rc = SEPOL_OK;
+	struct cil_symtab_datum *s1 = avrule->src;
+	struct cil_symtab_datum *t1 = avrule->tgt;
+	struct cil_list *cp1 = avrule->classperms;
+	struct cil_symtab_datum *s2 = target->src;
+	struct cil_symtab_datum *t2 = target->tgt;
+	struct cil_list *cp2 = target->classperms;
+
+	if (match_self != CIL_TRUE && avrule == target) goto exit;
+
+	if (avrule->rule_kind != target->rule_kind) goto exit;
+
+	if (!cil_type_match_any(s1, s2)) goto exit;
+
+	if (t1->fqn != CIL_KEY_SELF && t2->fqn != CIL_KEY_SELF) {
+		if (!cil_type_match_any(t1, t2)) goto exit;
+	} else {
+		if (t1->fqn == CIL_KEY_SELF && t2->fqn == CIL_KEY_SELF) {
+			/* The earlier check whether s1 and s2 matches is all that is needed */
+		} else if (t1->fqn == CIL_KEY_SELF) {
+			rc = cil_self_match_any(s1, s2, t2);
+			if (rc < 0) {
+				goto exit;
+			} else if (rc == CIL_FALSE) {
+				rc = SEPOL_OK;
+				goto exit;
+			}
+		} else if (t2->fqn == CIL_KEY_SELF) {
+			rc = cil_self_match_any(s2, s1, t1);
+			if (rc < 0) {
+				goto exit;
+			} else if (rc == CIL_FALSE) {
+				rc = SEPOL_OK;
+				goto exit;
+			}
+		}
+	}
+
+	if (cil_classperms_list_match_any(cp1, cp2)) {
+		cil_list_append(matching, CIL_NODE, node);
+	}
+
+	rc = SEPOL_OK;
+
+exit:
+	return rc;
+}
+
+static int __cil_find_matching_avrule_in_ast(struct cil_tree_node *node,  __attribute__((unused)) uint32_t *finished, void *extra_args)
+{
+	int rc = SEPOL_OK;
+	struct cil_args_find *args = extra_args;
+
+	if (node->flavor == CIL_BLOCK) {
+		struct cil_block *blk = node->data;
+		if (blk->is_abstract == CIL_TRUE) {
+			*finished = CIL_TREE_SKIP_HEAD;
+			goto exit;
+		}
+	} else if (node->flavor == CIL_MACRO) {
+		*finished = CIL_TREE_SKIP_HEAD;
+		goto exit;
+	} else if (node->flavor == CIL_AVRULE) {
+		rc = cil_find_matching_avrule(node, node->data, args->target, args->matching, args->match_self);
+	}
+
+exit:
+	return rc;
+}
+
+int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self)
+{
+	int rc;
+	struct cil_args_find args;
+
+	args.flavor = flavor;
+	args.target = target;
+	args.matching = matching;
+	args.match_self = match_self;
+
+	rc = cil_tree_walk(current, __cil_find_matching_avrule_in_ast, NULL, NULL, &args);
+	if (rc) {
+		cil_log(CIL_ERR, "An error occured while searching for avrule in AST\n");
+	}
+
+	return rc;
+}
diff --git a/libsepol/cil/src/cil_find.h b/libsepol/cil/src/cil_find.h
new file mode 100644
index 0000000..c8ca2d2
--- /dev/null
+++ b/libsepol/cil/src/cil_find.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Tresys Technology, LLC. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``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 TRESYS TECHNOLOGY, LLC 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.
+ *
+ * The views and conclusions contained in the software and documentation are those
+ * of the authors and should not be interpreted as representing official policies,
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
+#include "cil_flavor.h"
+#include "cil_tree.h"
+#include "cil_list.h"
+
+#ifndef CIL_FIND_H_
+#define CIL_FIND_H_
+
+int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self);
+
+#endif
diff --git a/libsepol/cil/src/cil_flavor.h b/libsepol/cil/src/cil_flavor.h
index d839f68..9fb5083 100644
--- a/libsepol/cil/src/cil_flavor.h
+++ b/libsepol/cil/src/cil_flavor.h
@@ -63,6 +63,7 @@
 	CIL_CLASSPERMISSIONSET,
 	CIL_USERPREFIX,
 	CIL_USERROLE,
+	CIL_USERATTRIBUTESET,
 	CIL_USERLEVEL,
 	CIL_USERRANGE,
 	CIL_USERBOUNDS,
@@ -83,6 +84,7 @@
 	CIL_SIDORDER,
 	CIL_ROLEALLOW,
 	CIL_AVRULE,
+	CIL_AVRULEX,
 	CIL_ROLETRANSITION,
 	CIL_TYPE_RULE,
 	CIL_NAMETYPETRANSITION,
@@ -163,6 +165,7 @@
 	CIL_MAP_CLASS,
 	CIL_CLASSPERMISSION,
 	CIL_USER,
+	CIL_USERATTRIBUTE,
 	CIL_ROLE,
 	CIL_ROLEATTRIBUTE,
 	CIL_TYPE,
@@ -180,6 +183,7 @@
 	CIL_CONTEXT,
 	CIL_IPADDR,
 	CIL_POLICYCAP,
+	CIL_PERMISSIONX
 };
 
 
diff --git a/libsepol/cil/src/cil_fqn.c b/libsepol/cil/src/cil_fqn.c
index dbdd995..865bd7d 100644
--- a/libsepol/cil/src/cil_fqn.c
+++ b/libsepol/cil/src/cil_fqn.c
@@ -102,6 +102,7 @@
 		case CIL_SYM_LEVELRANGES:
 		case CIL_SYM_IPADDRS:
 		case CIL_SYM_NAMES:
+		case CIL_SYM_PERMX:
 			/* These do not show up in the kernal policy */
 			break;
 		case CIL_SYM_POLICYCAPS:
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index a43d111..a736eff 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -127,6 +127,8 @@
 char *CIL_KEY_TYPE;
 char *CIL_KEY_ROLE;
 char *CIL_KEY_USER;
+char *CIL_KEY_USERATTRIBUTE;
+char *CIL_KEY_USERATTRIBUTESET;
 char *CIL_KEY_SENSITIVITY;
 char *CIL_KEY_CATEGORY;
 char *CIL_KEY_CATSET;
@@ -216,6 +218,11 @@
 char *CIL_KEY_ROOT;
 char *CIL_KEY_NODE;
 char *CIL_KEY_PERM;
+char *CIL_KEY_ALLOWX;
+char *CIL_KEY_AUDITALLOWX;
+char *CIL_KEY_DONTAUDITX;
+char *CIL_KEY_PERMISSIONX;
+char *CIL_KEY_IOCTL;
 
 /*
 	Symbol Table Array Indices
@@ -239,6 +246,7 @@
 	CIL_SYM_POLICYCAPS,
 	CIL_SYM_IPADDRS,
 	CIL_SYM_NAMES,
+	CIL_SYM_PERMX,
 	CIL_SYM_NUM,
 	CIL_SYM_UNKNOWN,
 	CIL_SYM_PERMS	// Special case for permissions. This symtab is not included in arrays
@@ -279,11 +287,15 @@
 	struct cil_list *userprefixes;
 	struct cil_list *selinuxusers;
 	struct cil_list *names;
+	int num_types_and_attrs;
+	int num_classes;
 	int num_cats;
 	int num_types;
 	int num_roles;
+	int num_users;
 	struct cil_type **val_to_type;
 	struct cil_role **val_to_role;
+	struct cil_user **val_to_user;
 	int disable_dontaudit;
 	int disable_neverallow;
 	int preserve_tunables;
@@ -410,14 +422,27 @@
 struct cil_user {
 	struct cil_symtab_datum datum;
 	struct cil_user *bounds;
-	struct cil_list *roles;
+	ebitmap_t *roles;
 	struct cil_level *dftlevel;
 	struct cil_levelrange *range;
+	int value;
+};
+
+struct cil_userattribute {
+	struct cil_symtab_datum datum;
+	struct cil_list *expr_list;
+	ebitmap_t *users;
+};
+
+struct cil_userattributeset {
+	char *attr_str;
+	struct cil_list *str_expr;
+	struct cil_list *datum_expr;
 };
 
 struct cil_userrole {
 	char *user_str;
-	struct cil_user *user;
+	void *user;
 	char *role_str;
 	void *role;
 };
@@ -552,6 +577,26 @@
 	struct cil_list *classperms;
 };
 
+#define CIL_PERMX_KIND_IOCTL 1
+struct cil_permissionx {
+	struct cil_symtab_datum datum;
+	uint32_t kind;
+	char *obj_str;
+	void *obj;
+	struct cil_list *expr_str;
+	ebitmap_t *perms;
+};
+
+struct cil_avrulex {
+	uint32_t rule_kind;
+	char *src_str;
+	void *src; /* type, alias, or attribute */
+	char *tgt_str;
+	void *tgt; /* type, alias, or attribute */
+	char *permx_str;
+	struct cil_permissionx *permx;
+};
+
 #define CIL_TYPE_TRANSITION 16
 #define CIL_TYPE_MEMBER     32
 #define CIL_TYPE_CHANGE     64
@@ -928,6 +973,8 @@
 void cil_tunable_init(struct cil_tunable **ciltun);
 void cil_tunif_init(struct cil_tunableif **tif);
 void cil_avrule_init(struct cil_avrule **avrule);
+void cil_avrulex_init(struct cil_avrulex **avrulex);
+void cil_permissionx_init(struct cil_permissionx **permx);
 void cil_type_rule_init(struct cil_type_rule **type_rule);
 void cil_roletransition_init(struct cil_roletransition **roletrans);
 void cil_roleallow_init(struct cil_roleallow **role_allow);
@@ -972,5 +1019,7 @@
 void cil_defaultrange_init(struct cil_defaultrange **def);
 void cil_handleunknown_init(struct cil_handleunknown **unk);
 void cil_mls_init(struct cil_mls **mls);
+void cil_userattribute_init(struct cil_userattribute **attribute);
+void cil_userattributeset_init(struct cil_userattributeset **attrset);
 
 #endif
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index eefcbc1..a9e2426 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -1155,11 +1155,6 @@
 		case CIL_USER:
 			cil_multimap_insert(users, node->data, NULL, CIL_USERROLE, CIL_NONE);
 			break;
-		case CIL_USERROLE: {
-			struct cil_userrole *userrole = node->data;
-			cil_multimap_insert(users, &userrole->user->datum, (struct cil_symtab_datum *)userrole->role, CIL_USERROLE, CIL_ROLE);
-		}
-			break;
 		case CIL_CATALIAS: {
 			struct cil_alias *alias = node->data;
 			struct cil_symtab_datum *datum = alias->actual;
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index f91727f..8050bbb 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -339,28 +339,53 @@
 	case CIL_MACRO:
 		*finished = CIL_TREE_SKIP_HEAD;
 		break;
-	case CIL_TYPE: {
-		struct cil_type *type = node->data;
-		if (type->datum.nodes->head->data == node) {
-			// multiple AST nodes can point to the same cil_type data (like if
-			// copied from a macro). This check ensures we only count the
-			// duplicates once
-			type->value = db->num_types;
-			db->num_types++;
+	case CIL_CLASS: {
+		struct cil_class *class = node->data;
+		if (class->datum.nodes->head->data == node) {
+			// Multiple nodes can point to the same datum. Only count once.
+			db->num_classes++;
 		}
 		break;
 	}
+	case CIL_TYPE: {
+		struct cil_type *type = node->data;
+		if (type->datum.nodes->head->data == node) {
+			// Multiple nodes can point to the same datum. Only count once.
+			type->value = db->num_types;
+			db->num_types++;
+			db->num_types_and_attrs++;
+		}
+		break;
+	}
+	case CIL_TYPEATTRIBUTE: {
+		struct cil_typeattribute *attr = node->data;
+		if (attr->datum.nodes->head->data == node) {
+			// Multiple nodes can point to the same datum. Only count once.
+			db->num_types_and_attrs++;
+		}
+		break;
+	}
+
 	case CIL_ROLE: {
 		struct cil_role *role = node->data;
 		if (role->datum.nodes->head->data == node) {
-			// multiple AST nodes can point to the same cil_role data (like if
-			// copied from a macro). This check ensures we only count the
-			// duplicates once
+			// Multiple nodes can point to the same datum. Only count once.
 			role->value = db->num_roles;
 			db->num_roles++;
 		}
 		break;
 	}
+	case CIL_USER: {
+		struct cil_user *user = node->data;
+		if (user->datum.nodes->head->data == node) {
+			// multiple AST nodes can point to the same cil_user data (like if
+			// copied from a macro). This check ensures we only count the
+			// duplicates once
+			user->value = db->num_users;
+			db->num_users++;
+		}
+		break;
+	}
 	case CIL_NETIFCON:
 		db->netifcon->count++;
 		break;
@@ -432,6 +457,14 @@
 		db->val_to_role[role->value] = role;
 		break;
 	}
+	case CIL_USER: {
+		struct cil_user *user= node->data;
+		if (db->val_to_user == NULL) {
+			db->val_to_user = cil_malloc(sizeof(*db->val_to_user) * db->num_users);
+		}
+		db->val_to_user[user->value] = user;
+		break;
+	}
 	case CIL_USERPREFIX: {
 		cil_list_append(db->userprefixes, CIL_USERPREFIX, node->data);
 		break;
@@ -624,6 +657,54 @@
 	return rc;
 }
 
+static int __evaluate_user_expression(struct cil_userattribute *attr, struct cil_db *db)
+{
+	int rc;
+
+	attr->users = cil_malloc(sizeof(*attr->users));
+	rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->users, db->num_users, db);
+	if (rc != SEPOL_OK) {
+		cil_log(CIL_ERR, "Failed to expand user attribute to bitmap\n");
+		ebitmap_destroy(attr->users);
+		free(attr->users);
+		attr->users = NULL;
+	}
+	return rc;
+}
+
+static int __cil_user_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
+{
+	int rc = SEPOL_ERR;
+	struct cil_tree_node *node = datum->nodes->head->data;
+	struct cil_userattribute *attr = NULL;
+	struct cil_user *user = NULL;
+
+	ebitmap_init(bitmap);
+
+	if (node->flavor == CIL_USERATTRIBUTE) {
+		attr = (struct cil_userattribute *)datum;
+		if (attr->users == NULL) {
+			rc = __evaluate_user_expression(attr, db);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+		}
+		ebitmap_union(bitmap, attr->users);
+	} else {
+		user = (struct cil_user *)datum;
+		if (ebitmap_set_bit(bitmap, user->value, 1)) {
+			cil_log(CIL_ERR, "Failed to set user bit\n");
+			ebitmap_destroy(bitmap);
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 static int __evaluate_role_expression(struct cil_roleattribute *attr, struct cil_db *db)
 {
 	int rc;
@@ -668,6 +749,70 @@
 	return rc;
 }
 
+static int __evaluate_permissionx_expression(struct cil_permissionx *permx, struct cil_db *db)
+{
+	int rc;
+
+	permx->perms = cil_malloc(sizeof(*permx->perms));
+	ebitmap_init(permx->perms);
+
+	rc = __cil_expr_to_bitmap(permx->expr_str, permx->perms, 0x10000, db); // max is one more than 0xFFFF
+	if (rc != SEPOL_OK) {
+		cil_log(CIL_ERR, "Failed to expand permissionx expression\n");
+		ebitmap_destroy(permx->perms);
+		free(permx->perms);
+		permx->perms = NULL;
+	}
+
+	return rc;
+}
+
+static int __cil_permx_str_to_int(char *permx_str, uint16_t *val)
+{
+	char *endptr = NULL;
+	long lval = strtol(permx_str, &endptr, 0);
+
+	if (*endptr != '\0') {
+		cil_log(CIL_ERR, "permissionx value %s not valid number\n", permx_str);
+		goto exit;
+	}
+	if (lval < 0x0000 || lval > 0xFFFF) {
+		cil_log(CIL_ERR, "permissionx value %s must be between 0x0000 and 0xFFFF\n", permx_str);
+		goto exit;
+	}
+
+	*val = (uint16_t)lval;
+
+	return SEPOL_OK;
+
+exit:
+	return SEPOL_ERR;
+}
+
+static int __cil_permx_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
+{
+	int rc = SEPOL_ERR;
+	uint16_t val;
+
+	ebitmap_init(bitmap);
+
+	rc = __cil_permx_str_to_int((char*)datum, &val);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	if (ebitmap_set_bit(bitmap, (unsigned int)val, 1)) {
+		cil_log(CIL_ERR, "Failed to set permissionx bit\n");
+		ebitmap_destroy(bitmap);
+		goto exit;
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 static int __cil_perm_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
 {
 	struct cil_perm *perm = (struct cil_perm *)datum;
@@ -778,7 +923,7 @@
 	return rc;
 }
 
-static int __cil_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
+static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
 {
 	int rc = SEPOL_ERR;
 	struct cil_symtab_datum *d1 = i1->data;
@@ -818,6 +963,39 @@
 	return rc;
 }
 
+static int __cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
+{
+	int rc = SEPOL_ERR;
+	char *p1 = i1->data;
+	char *p2 = i2->data;
+	uint16_t v1;
+	uint16_t v2;
+	uint32_t i;
+
+	rc = __cil_permx_str_to_int(p1, &v1);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	rc = __cil_permx_str_to_int(p2, &v2);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	for (i = v1; i <= v2; i++) {
+		if (ebitmap_set_bit(bitmap, i, 1)) {
+			cil_log(CIL_ERR, "Failed to set permissionx bit\n");
+			ebitmap_destroy(bitmap);
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 static int __cil_expr_to_bitmap_helper(struct cil_list_item *curr, enum cil_flavor flavor, ebitmap_t *bitmap, int max, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
@@ -830,6 +1008,9 @@
 		case CIL_ROLE:
 			rc = __cil_role_to_bitmap(curr->data, bitmap, db);
 			break;
+		case CIL_USER:
+			rc = __cil_user_to_bitmap(curr->data, bitmap, db);
+			break;
 		case CIL_PERM:
 			rc = __cil_perm_to_bitmap(curr->data, bitmap, db);
 			break;
@@ -846,6 +1027,10 @@
 		if (rc != SEPOL_OK) {
 			ebitmap_destroy(bitmap);
 		}	
+	} else if (flavor == CIL_PERMISSIONX) {
+		// permissionx expressions aren't resolved into anything, so curr->flavor
+		// is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those
+		rc = __cil_permx_to_bitmap(curr->data, bitmap, db);
 	}
 
 	return rc;
@@ -878,18 +1063,27 @@
 				goto exit;
 			}
 		} else if (op == CIL_RANGE) {
-			if (flavor != CIL_CAT) {
-				cil_log(CIL_INFO, "Range operation only supported for categories\n");
+			if (flavor == CIL_CAT) {
+				ebitmap_init(&tmp);
+				rc = __cil_cat_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
+				if (rc != SEPOL_OK) {
+					cil_log(CIL_INFO, "Failed to expand category range\n");
+					ebitmap_destroy(&tmp);
+					goto exit;
+				}
+			} else if (flavor == CIL_PERMISSIONX) {
+				ebitmap_init(&tmp);
+				rc = __cil_permissionx_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
+				if (rc != SEPOL_OK) {
+					cil_log(CIL_INFO, "Failed to expand category range\n");
+					ebitmap_destroy(&tmp);
+					goto exit;
+				}
+			} else {
+				cil_log(CIL_INFO, "Range operation only supported for categories permissionx\n");
 				rc = SEPOL_ERR;
 				goto exit;
 			}
-			ebitmap_init(&tmp);
-			rc = __cil_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
-			if (rc != SEPOL_OK) {
-				cil_log(CIL_INFO, "Failed to expand category range\n");
-				ebitmap_destroy(&tmp);
-				goto exit;
-			}
 		} else {
 			rc = __cil_expr_to_bitmap_helper(curr->next, flavor, &b1, max, db);
 			if (rc != SEPOL_OK) {
@@ -1025,6 +1219,30 @@
 		}
 		break;
 	}
+	case CIL_AVRULEX: {
+		struct cil_avrulex *rule = node->data;
+		if (rule->permx_str == NULL) {
+			rc = __evaluate_permissionx_expression(rule->permx, db);
+			if (rc != SEPOL_OK) goto exit;
+		}
+		break;
+	}
+	case CIL_PERMISSIONX: {
+		struct cil_permissionx *permx = node->data;
+		rc = __evaluate_permissionx_expression(permx, db);
+		if (rc != SEPOL_OK) goto exit;
+		break;
+	}
+	case CIL_USERATTRIBUTE: {
+		struct cil_userattribute *attr = node->data;
+		if (attr->users == NULL) {
+			rc = __evaluate_user_expression(attr, db);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+		}
+		break;
+	}
 	default:
 		break;
 	}
@@ -1130,6 +1348,102 @@
 	return rc;
 }
 
+static int __cil_user_assign_roles(struct cil_user *user, struct cil_symtab_datum *datum)
+{
+	struct cil_tree_node *node = datum->nodes->head->data;
+	struct cil_role *role = NULL;
+	struct cil_roleattribute *attr = NULL;
+
+	if (user->roles == NULL) {
+		user->roles = cil_malloc(sizeof(*user->roles));
+		ebitmap_init(user->roles);
+	}
+
+	if (node->flavor == CIL_ROLE) {
+		role = (struct cil_role *)datum;
+		if (ebitmap_set_bit(user->roles, role->value, 1)) {
+			cil_log(CIL_INFO, "Failed to set bit in user roles bitmap\n");
+			goto exit;
+		}
+	} else if (node->flavor == CIL_ROLEATTRIBUTE) {
+		attr = (struct cil_roleattribute *)datum;
+		ebitmap_union(user->roles, attr->roles);
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return SEPOL_ERR;
+}
+
+static int __cil_post_db_userrole_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
+{
+	int rc = SEPOL_ERR;
+	struct cil_db *db = extra_args;
+	struct cil_block *blk = NULL;
+	struct cil_userrole *userrole = NULL;
+	struct cil_symtab_datum *user_datum = NULL;
+	struct cil_symtab_datum *role_datum = NULL;
+	struct cil_tree_node *user_node = NULL;
+	struct cil_userattribute *u_attr = NULL;
+	unsigned int i;
+	struct cil_user *user = NULL;
+	ebitmap_node_t *unode = NULL;
+
+	switch (node->flavor) {
+	case CIL_BLOCK: {
+		blk = node->data;
+		if (blk->is_abstract == CIL_TRUE) {
+			*finished = CIL_TREE_SKIP_HEAD;
+		}
+		break;
+	}
+	case CIL_MACRO: {
+		*finished = CIL_TREE_SKIP_HEAD;
+		break;
+	}
+	case CIL_USERROLE: {
+		userrole = node->data;
+		user_datum = userrole->user;
+		role_datum = userrole->role;
+		user_node = user_datum->nodes->head->data;
+
+		if (user_node->flavor == CIL_USERATTRIBUTE) {
+			u_attr = userrole->user;
+
+			ebitmap_for_each_bit(u_attr->users, unode, i) {
+				if (!ebitmap_get_bit(u_attr->users, i)) {
+					continue;
+				}
+
+				user = db->val_to_user[i];
+
+				rc = __cil_user_assign_roles(user, role_datum);
+				if (rc != SEPOL_OK) {
+					goto exit;
+				}
+			}
+		} else {
+			user = userrole->user;
+
+			rc = __cil_user_assign_roles(user, role_datum);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+		}
+
+		break;
+	}
+	default:
+		break;
+	}
+
+	return SEPOL_OK;
+exit:
+	cil_log(CIL_INFO, "cil_post_db_userrole_helper failed\n");
+	return rc;
+}
+
 static int __evaluate_level_expression(struct cil_level *level, struct cil_db *db)
 {
 	if (level->cats != NULL) {
@@ -1601,6 +1915,12 @@
 		goto exit;
 	}
 
+	rc = cil_tree_walk(db->ast->root, __cil_post_db_userrole_helper, NULL, NULL, db);
+	if (rc != SEPOL_OK) {
+		cil_log(CIL_INFO, "Failed during userrole association\n");
+		goto exit;
+	}
+
 	rc = cil_tree_walk(db->ast->root, __cil_post_db_classperms_helper, NULL, NULL, db);
 	if (rc != SEPOL_OK) {
 		cil_log(CIL_INFO, "Failed to evaluate class mapping permissions expressions\n");
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
index 92f7720..09cff05 100644
--- a/libsepol/cil/src/cil_reset_ast.c
+++ b/libsepol/cil/src/cil_reset_ast.c
@@ -99,7 +99,32 @@
 	user->bounds = NULL;
 	user->dftlevel = NULL;
 	user->range = NULL;
-	cil_list_destroy(&user->roles, CIL_FALSE);
+}
+
+static void cil_reset_userattr(struct cil_userattribute *attr)
+{
+	struct cil_list_item *expr = NULL;
+	struct cil_list_item *next = NULL;
+
+	/* during a re-resolve, we need to reset the lists of expression stacks associated with this attribute from a userattribute statement */
+	if (attr->expr_list != NULL) {
+		/* we don't want to destroy the expression stacks (cil_list) inside
+		 * this list cil_list_destroy destroys sublists, so we need to do it
+		 * manually */
+		expr = attr->expr_list->head;
+		while (expr != NULL) {
+			next = expr->next;
+			cil_list_item_destroy(&expr, CIL_FALSE);
+			expr = next;
+		}
+		free(attr->expr_list);
+		attr->expr_list = NULL;
+	}
+}
+
+static void cil_reset_userattributeset(struct cil_userattributeset *uas)
+{
+	cil_list_destroy(&uas->datum_expr, CIL_FALSE);
 }
 
 static void cil_reset_selinuxuser(struct cil_selinuxuser *selinuxuser)
@@ -403,6 +428,12 @@
 	case CIL_USER:
 		cil_reset_user(node->data);
 		break;
+	case CIL_USERATTRIBUTE:
+		cil_reset_userattr(node->data);
+		break;
+	case CIL_USERATTRIBUTESET:
+		cil_reset_userattributeset(node->data);
+		break;
 	case CIL_SELINUXUSERDEFAULT:
 	case CIL_SELINUXUSER:
 		cil_reset_selinuxuser(node->data);
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index c9738da..e332cbd 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -51,7 +51,7 @@
 	struct cil_db *db;
 	enum cil_pass pass;
 	uint32_t *changed;
-	struct cil_tree_node *callstack;
+	char *last_resolved_name;
 	struct cil_tree_node *optstack;
 	struct cil_tree_node *boolif;
 	struct cil_tree_node *macro;
@@ -319,6 +319,75 @@
 	return rc;
 }
 
+int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, void *extra_args)
+{
+	struct cil_symtab_datum *obj_datum = NULL;
+	int rc = SEPOL_ERR;
+
+	rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+	permx->obj = (struct cil_class*)obj_datum;
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
+int cil_resolve_avrulex(struct cil_tree_node *current, void *extra_args)
+{
+	struct cil_args_resolve *args = extra_args;
+	struct cil_db *db = NULL;
+
+	struct cil_avrulex *rule = current->data;
+	struct cil_symtab_datum *src_datum = NULL;
+	struct cil_symtab_datum *tgt_datum = NULL;
+	struct cil_symtab_datum *permx_datum = NULL;
+	int rc = SEPOL_ERR;
+
+	if (args != NULL) {
+		db = args->db;
+	}
+
+	rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, args, &src_datum);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+	rule->src = src_datum;
+	cil_type_used(src_datum);
+
+	if (rule->tgt_str == CIL_KEY_SELF) {
+		rule->tgt = db->selftype;
+	} else {
+		rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+		rule->tgt = tgt_datum;
+		cil_type_used(tgt_datum);
+	}
+
+	if (rule->permx_str != NULL) {
+		rc = cil_resolve_name(current, rule->permx_str, CIL_SYM_PERMX, args, &permx_datum);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+		rule->permx = (struct cil_permissionx*)permx_datum;
+	} else {
+		rc = cil_resolve_permissionx(current, rule->permx, extra_args);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+	}
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args)
 {
 	struct cil_type_rule *rule = current->data;
@@ -750,12 +819,6 @@
 	}
 	userrole->role = role_datum;
 
-	if (userrole->user->roles == NULL) {
-		cil_list_init(&userrole->user->roles, CIL_LIST_ITEM);
-	}
-
-	cil_list_append(userrole->user->roles, CIL_ROLE, userrole->role);
-
 	return SEPOL_OK;
 
 exit:
@@ -768,12 +831,22 @@
 	struct cil_symtab_datum *user_datum = NULL;
 	struct cil_symtab_datum *lvl_datum = NULL;
 	struct cil_user *user = NULL;
+	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
 	rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, extra_args, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
+
+	user_node = user_datum->nodes->head->data;
+
+	if (user_node->flavor != CIL_USER) {
+		cil_log(CIL_ERR, "Userlevel must be a user\n");
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
 	user = (struct cil_user*)user_datum;
 
 	if (usrlvl->level_str != NULL) {
@@ -811,12 +884,22 @@
 	struct cil_symtab_datum *user_datum = NULL;
 	struct cil_symtab_datum *range_datum = NULL;
 	struct cil_user *user = NULL;
+	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
 	rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, extra_args, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
+
+	user_node = user_datum->nodes->head->data;
+
+	if (user_node->flavor != CIL_USER) {
+		cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn);
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
 	user = (struct cil_user*)user_datum;
 
 	if (userrange->range_str != NULL) {
@@ -852,12 +935,22 @@
 {
 	struct cil_userprefix *userprefix = current->data;
 	struct cil_symtab_datum *user_datum = NULL;
+	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
 	rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, extra_args, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
+
+	user_node = user_datum->nodes->head->data;
+
+	if (user_node->flavor != CIL_USER) {
+		cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn);
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
 	userprefix->user = (struct cil_user*)user_datum;
 
 exit:
@@ -869,18 +962,27 @@
 	struct cil_selinuxuser *selinuxuser = current->data;
 	struct cil_symtab_datum *user_datum = NULL;
 	struct cil_symtab_datum *lvlrange_datum = NULL;
+	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
 	rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, extra_args, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
+
+	user_node = user_datum->nodes->head->data;
+
+	if (user_node->flavor != CIL_USER) {
+		cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn);
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
 	selinuxuser->user = (struct cil_user*)user_datum;
 
 	if (selinuxuser->range_str != NULL) {
 		rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
 		if (rc != SEPOL_OK) {
-			cil_log(CIL_ERR, "Unable to resolve name: %s\n", selinuxuser->range_str);
 			goto exit;
 		}
 		selinuxuser->range = (struct cil_levelrange*)lvlrange_datum;
@@ -1455,7 +1557,6 @@
 
 	rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, extra_args);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR,"Unable to resolve categories\n");
 		goto exit;
 	}
 	
@@ -1647,34 +1748,48 @@
 	struct cil_symtab_datum *user_datum = NULL;
 	struct cil_symtab_datum *role_datum = NULL;
 	struct cil_symtab_datum *type_datum = NULL;
-	struct cil_tree_node *type_node = NULL;
+	struct cil_tree_node *node = NULL;
 	struct cil_symtab_datum *lvlrange_datum = NULL;
 
 	int rc = SEPOL_ERR;
 
 	rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, extra_args, &user_datum);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->user_str);
 		goto exit;
 	}
+
+	node = user_datum->nodes->head->data;
+
+	if (node->flavor != CIL_USER) {
+		cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn);
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
 	context->user = (struct cil_user*)user_datum;
 
 	rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->role_str);
 		goto exit;
 	}
+
+	node = role_datum->nodes->head->data;
+	if (node->flavor != CIL_ROLE) {
+		rc = SEPOL_ERR;
+		cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn);
+		goto exit;
+	}
+
 	context->role = (struct cil_role*)role_datum;
 
 	rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
 	if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->type_str);
 		goto exit;
 	}
 
-	type_node = type_datum->nodes->head->data;
+	node = type_datum->nodes->head->data;
 
-	if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) {
+	if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) {
 		rc = SEPOL_ERR;
 		cil_log(CIL_ERR, "Type not a type or type alias\n");
 		goto exit;
@@ -1684,7 +1799,6 @@
 	if (context->range_str != NULL) {
 		rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
 		if (rc != SEPOL_OK) {
-			cil_log(CIL_ERR, "Unable to resolve name: %s\n", context->range_str);
 			goto exit;
 		}
 		context->range = (struct cil_levelrange*)lvlrange_datum;
@@ -2095,6 +2209,73 @@
 	return rc;
 }
 
+void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node)
+{
+	struct cil_list *trace = NULL;
+	struct cil_list_item *item = NULL;
+	struct cil_tree_node *curr = NULL;
+
+	cil_list_init(&trace, CIL_NODE);
+
+	for (curr = bi_node; curr != terminating_node; curr = curr->parent) {
+		if (curr->flavor == CIL_BLOCK) {
+			cil_list_prepend(trace, CIL_NODE, curr);
+		} else {
+			if (curr != bi_node) {
+				cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_blockinherit *)curr->data)->block));
+			}
+			cil_list_prepend(trace, CIL_NODE, curr);
+		}
+	}
+	cil_list_prepend(trace, CIL_NODE, terminating_node);
+
+	cil_list_for_each(item, trace) {
+		curr = item->data;
+		cil_log(CIL_ERR, "  %s:%d: ", curr->path, curr->line);
+
+		if (curr->flavor == CIL_BLOCK) {
+			cil_log(CIL_ERR, "block %s\n", DATUM(curr->data)->name);
+		} else {
+			cil_log(CIL_ERR, "blockinherit %s\n", ((struct cil_blockinherit *)curr->data)->block_str);
+		}
+	}
+
+	cil_list_destroy(&trace, CIL_FALSE);
+}
+
+int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node)
+{
+	struct cil_tree_node *curr = NULL;
+	struct cil_blockinherit *bi = NULL;
+	struct cil_block *block = NULL;
+	int rc = SEPOL_ERR;
+
+	bi = bi_node->data;
+
+	for (curr = bi_node->parent; curr != NULL; curr = curr->parent) {
+		if (curr->flavor != CIL_BLOCK) {
+			continue;
+		}
+
+		block = curr->data;
+
+		if (block != bi->block) {
+			continue;
+		}
+
+		cil_log(CIL_ERR, "Recursive blockinherit found:\n");
+		cil_print_recursive_blockinherit(bi_node, curr);
+
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
+	rc = SEPOL_OK;
+
+exit:
+	return rc;
+}
+
 int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args)
 {
 	struct cil_block *block = current->data;
@@ -2118,6 +2299,11 @@
 	}
 
 	cil_list_for_each(item, block->bi_nodes) {
+		rc = cil_check_recursive_blockinherit(item->data);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+
 		rc = cil_copy_ast(db, current, item->data);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n");
@@ -2351,7 +2537,6 @@
 	cil_list_for_each(curr, def->class_strs) {
 		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
 		if (rc != SEPOL_OK) {
-			cil_log(CIL_ERR, "Failed to resolve class %s in %s\n", (char *)curr->data, cil_node_to_string(current));
 			goto exit;
 		}
 		cil_list_append(def->class_datums, CIL_CLASS, datum);
@@ -2375,7 +2560,6 @@
 	cil_list_for_each(curr, def->class_strs) {
 		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
 		if (rc != SEPOL_OK) {
-			cil_log(CIL_ERR, "Failed to resolve class %s in defaultrange\n", (char *)curr->data);
 			goto exit;
 		}
 		cil_list_append(def->class_datums, CIL_CLASS, datum);
@@ -2387,6 +2571,80 @@
 	return rc;
 }
 
+void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *terminating_node)
+{
+	struct cil_list *trace = NULL;
+	struct cil_list_item * item = NULL;
+	struct cil_tree_node *curr = NULL;
+
+	cil_list_init(&trace, CIL_NODE);
+
+	for (curr = call_node; curr != terminating_node; curr = curr->parent) {
+		if (curr->flavor == CIL_CALL) {
+			if (curr != call_node) {
+				cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)curr->data)->macro));
+			}
+			cil_list_prepend(trace, CIL_NODE, curr);
+		}
+	}
+
+	if (terminating_node->flavor == CIL_MACRO) {
+		cil_list_prepend(trace, CIL_NODE, terminating_node);
+	} else {
+		cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)terminating_node->data)->macro));
+	}
+
+	cil_list_for_each(item, trace) {
+		curr = item->data;
+		cil_log(CIL_ERR, "  %s:%d: ", curr->path, curr->line);
+
+		if (curr->flavor == CIL_MACRO) {
+			cil_log(CIL_ERR, "macro %s\n", DATUM(curr->data)->name);
+		} else {
+			cil_log(CIL_ERR, "call %s\n", ((struct cil_call *)curr->data)->macro_str);
+		}
+	}
+
+	cil_list_destroy(&trace, CIL_FALSE);
+}
+
+int cil_check_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *macro_node)
+{
+	struct cil_tree_node *curr = NULL;
+	struct cil_call * call = NULL;
+	int rc = SEPOL_ERR;
+
+	for (curr = call_node; curr != NULL; curr = curr->parent) {
+		if (curr->flavor == CIL_CALL) {
+			if (curr == call_node) {
+				continue;
+			}
+
+			call = curr->data;
+			if (call->macro != macro_node->data) {
+				continue;
+			}
+		} else if (curr->flavor == CIL_MACRO) {
+			if (curr != macro_node) {
+				rc = SEPOL_OK;
+				goto exit;
+			}
+		} else {
+			continue;
+		}
+
+		cil_log(CIL_ERR, "Recursive macro call found:\n");
+		cil_print_recursive_call(call_node, curr);
+
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
+	rc = SEPOL_OK;
+exit:
+	return rc;
+}
+
 int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
 {
 	struct cil_call *new_call = current->data;
@@ -2408,7 +2666,7 @@
 	macro_node = macro_datum->nodes->head->data;
 
 	if (macro_node->flavor != CIL_MACRO) {
-		printf("Failed to resolve macro %s\n", new_call->macro_str);
+		printf("Failed to resolve %s to a macro\n", new_call->macro_str);
 		rc = SEPOL_ERR;
 		goto exit;
 	}
@@ -2623,6 +2881,12 @@
 
 	if (new_call->copied == 0) {
 		new_call->copied = 1;
+
+		rc = cil_check_recursive_call(current, macro_node);
+		if (rc != SEPOL_OK) {
+			goto exit;
+		}
+
 		rc = cil_copy_ast(db, macro_node, current);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc);
@@ -2974,6 +3238,48 @@
 	return rc;
 }
 
+int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args)
+{
+	int rc = SEPOL_ERR;
+	struct cil_userattributeset *attrusers = current->data;
+	struct cil_symtab_datum *attr_datum = NULL;
+	struct cil_tree_node *attr_node = NULL;
+	struct cil_userattribute *attr = NULL;
+
+	rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, extra_args, &attr_datum);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+	attr_node = attr_datum->nodes->head->data;
+
+	if (attr_node->flavor != CIL_USERATTRIBUTE) {
+		rc = SEPOL_ERR;
+		cil_log(CIL_ERR, "Attribute user not an attribute\n");
+		goto exit;
+	}
+	attr = (struct cil_userattribute*)attr_datum;
+
+	rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, extra_args);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	rc = cil_verify_no_self_reference(attr_datum, attrusers->datum_expr);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	if (attr->expr_list == NULL) {
+		cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE);
+	}
+
+	cil_list_append(attr->expr_list, CIL_LIST, attrusers->datum_expr);
+
+	return SEPOL_OK;
+
+exit:
+	return rc;
+}
 
 int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 {
@@ -3128,6 +3434,12 @@
 		case CIL_AVRULE:
 			rc = cil_resolve_avrule(node, args);
 			break;
+		case CIL_AVRULEX:
+			rc = cil_resolve_avrulex(node, args);
+			break;
+		case CIL_PERMISSIONX:
+			rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, args);
+			break;
 		case CIL_TYPE_RULE:
 			rc = cil_resolve_type_rule(node, args);
 			break;
@@ -3228,6 +3540,9 @@
 		case CIL_DEFAULTRANGE:
 			rc = cil_resolve_defaultrange(node, args);
 			break;
+		case CIL_USERATTRIBUTESET:
+			rc = cil_resolve_userattributeset(node, args);
+			break;
 		default:
 			break;
 		}
@@ -3250,6 +3565,7 @@
 	struct cil_tree_node *optstack = args->optstack;
 	struct cil_tree_node *boolif = args->boolif;
 	struct cil_tree_node *blockstack = args->blockstack;
+	struct cil_tree_node *macro = args->macro;
 
 	if (node == NULL) {
 		goto exit;
@@ -3272,6 +3588,17 @@
 		}
 	}
 
+	if (macro != NULL) {
+		if (node->flavor == CIL_BLOCKINHERIT ||
+			node->flavor == CIL_BLOCK ||
+			node->flavor == CIL_BLOCKABSTRACT ||
+			node->flavor == CIL_MACRO) {
+			cil_log(CIL_ERR, "%s statement is not allowed in macros (%s:%d)\n", cil_node_to_string(node), node->path, node->line);
+			rc = SEPOL_ERR;
+			goto exit;
+		}
+	}
+
 	if (boolif != NULL) {
 		if (!(node->flavor == CIL_CONDBLOCK ||
 			node->flavor == CIL_AVRULE ||
@@ -3304,14 +3631,22 @@
 	}
 
 	rc = __cil_resolve_ast_node(node, extra_args);
-	if (rc == SEPOL_ENOENT && optstack != NULL) {
-		struct cil_optional *opt = (struct cil_optional *)optstack->data;
-		cil_log(CIL_WARN, "Disabling optional %s at %d of %s\n", opt->datum.name, node->parent->line, node->parent->path);
-		/* disable an optional if something failed to resolve */
-		opt->enabled = CIL_FALSE;
-		rc = SEPOL_OK;
-	} else if (rc != SEPOL_OK) {
-		cil_log(CIL_ERR, "Failed to resolve %s statement at %d of %s\n", cil_node_to_string(node), node->line, node->path);
+	if (rc == SEPOL_ENOENT) {
+		enum cil_log_level lvl = CIL_ERR;
+
+		if (optstack != NULL) {
+			lvl = CIL_WARN;
+
+			struct cil_optional *opt = (struct cil_optional *)optstack->data;
+			struct cil_tree_node *opt_node = opt->datum.nodes->head->data;
+			cil_log(lvl, "Disabling optional '%s' at line %d of %s: ", opt->datum.name, opt_node->line, opt_node->path);
+			/* disable an optional if something failed to resolve */
+			opt->enabled = CIL_FALSE;
+			rc = SEPOL_OK;
+		}
+
+		cil_log(lvl, "Failed to resolve '%s' in %s statement at line %d of %s\n",
+		        args->last_resolved_name, cil_node_to_string(node), node->line, node->path);
 		goto exit;
 	}
 
@@ -3325,7 +3660,6 @@
 {
 	int rc = SEPOL_ERR;
 	struct cil_args_resolve *args = extra_args;
-	struct cil_tree_node *callstack = NULL;
 	struct cil_tree_node *optstack = NULL;
 	struct cil_tree_node *parent = NULL;
 	struct cil_tree_node *blockstack = NULL;
@@ -3335,36 +3669,18 @@
 		goto exit;
 	}
 
-	callstack = args->callstack;
 	optstack = args->optstack;
 	parent = current->parent;
 	blockstack = args->blockstack;
 
-	if (parent->flavor == CIL_CALL || parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) {
+	if (parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) {
 		/* push this node onto a stack */
 		cil_tree_node_init(&new);
 
 		new->data = parent->data;
 		new->flavor = parent->flavor;
 
-		if (parent->flavor == CIL_CALL) {
-			if (callstack != NULL) {
-				struct cil_tree_node *curr = NULL;
-				struct cil_call *new_call = new->data;
-				for (curr = callstack->cl_head; curr != NULL;
-					curr = curr->cl_head) {
-					struct cil_call *curr_call = curr->data;
-					if (curr_call->macro == new_call->macro) {
-						cil_log(CIL_ERR, "Recursive macro call found\n");
-						rc = SEPOL_ERR;
-						goto exit;
-					}
-				}
-				callstack->parent = new;
-				new->cl_head = callstack;
-			}
-			args->callstack = new;
-		} else if (parent->flavor == CIL_OPTIONAL) {
+		if (parent->flavor == CIL_OPTIONAL) {
 			if (optstack != NULL) {
 				optstack->parent = new;
 				new->cl_head = optstack;
@@ -3403,15 +3719,7 @@
 
 	parent = current->parent;
 
-	if (parent->flavor == CIL_CALL) {
-		/* pop off the stack */
-		struct cil_tree_node *callstack = args->callstack;
-		args->callstack = callstack->cl_head;
-		if (callstack->cl_head) {
-			callstack->cl_head->parent = NULL;
-		}
-		free(callstack);
-	} else if (parent->flavor == CIL_MACRO) {
+	if (parent->flavor == CIL_MACRO) {
 		args->macro = NULL;
 	} else if (parent->flavor == CIL_OPTIONAL) {
 		struct cil_tree_node *optstack;
@@ -3460,7 +3768,7 @@
 	extra_args.db = db;
 	extra_args.pass = pass;
 	extra_args.changed = &changed;
-	extra_args.callstack = NULL;
+	extra_args.last_resolved_name = NULL;
 	extra_args.optstack = NULL;
 	extra_args.boolif= NULL;
 	extra_args.macro = NULL;
@@ -3552,12 +3860,6 @@
 
 		/* reset the arguments */
 		changed = 0;
-		while (extra_args.callstack != NULL) {
-			struct cil_tree_node *curr = extra_args.callstack;
-			struct cil_tree_node *next = curr->cl_head;
-			free(curr);
-			extra_args.callstack = next;
-		}
 		while (extra_args.optstack != NULL) {
 			struct cil_tree_node *curr = extra_args.optstack;
 			struct cil_tree_node *next = curr->cl_head;
@@ -3579,6 +3881,12 @@
 
 	rc = SEPOL_OK;
 exit:
+	__cil_ordered_lists_destroy(&extra_args.sidorder_lists);
+	__cil_ordered_lists_destroy(&extra_args.classorder_lists);
+	__cil_ordered_lists_destroy(&extra_args.catorder_lists);
+	__cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists);
+	cil_list_destroy(&extra_args.in_list, CIL_FALSE);
+
 	return rc;
 }
 
@@ -3734,8 +4042,6 @@
 exit:
 	if (rc != SEPOL_OK) {
 		*datum = NULL;
-		cil_log(CIL_WARN, "Failed to resolve %s in %s statement on line %d of %s\n", 
-			name, cil_node_to_string(ast_node), ast_node->line, ast_node->path);
 	}
 
 	if (*datum != NULL) {
@@ -3752,5 +4058,7 @@
 		}
 	}
 
+	args->last_resolved_name = name;
+
 	return rc;
 }
diff --git a/libsepol/cil/src/cil_resolve_ast.h b/libsepol/cil/src/cil_resolve_ast.h
index e99f0a4..1175f97 100644
--- a/libsepol/cil/src/cil_resolve_ast.h
+++ b/libsepol/cil/src/cil_resolve_ast.h
@@ -54,6 +54,7 @@
 int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args);
 int cil_resolve_userbounds(struct cil_tree_node *current, void *extra_args);
 int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args);
+int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args);
 int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args);
 int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args);
 int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args);
diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c
index 6a731f2..f641baa 100644
--- a/libsepol/cil/src/cil_tree.c
+++ b/libsepol/cil/src/cil_tree.c
@@ -640,15 +640,18 @@
 		case CIL_USERROLE: {
 			struct cil_userrole *userrole = node->data;
 			cil_log(CIL_INFO, "USERROLE:");
+			struct cil_symtab_datum *datum = NULL;
 
 			if (userrole->user != NULL) {
-				cil_log(CIL_INFO, " %s", userrole->user->datum.name);
+				datum = userrole->user;
+				cil_log(CIL_INFO, " %s", datum->name);
 			} else if (userrole->user_str != NULL) {
 				cil_log(CIL_INFO, " %s", userrole->user_str);
 			}
 
 			if (userrole->role != NULL) {
-				cil_log(CIL_INFO, " %s", ((struct cil_symtab_datum *)userrole->role)->name);
+				datum = userrole->role;
+				cil_log(CIL_INFO, " %s", datum->name);
 			} else if (userrole->role_str != NULL) {
 				cil_log(CIL_INFO, " %s", userrole->role_str);
 			}
@@ -785,6 +788,21 @@
 			cil_log(CIL_INFO, "ROLEATTRIBUTE: %s\n", attr->datum.name);
 			return;
 		}
+		case CIL_USERATTRIBUTESET: {
+			struct cil_userattributeset *attr = node->data;
+
+			cil_log(CIL_INFO, "(USERATTRIBUTESET %s ", attr->attr_str);
+
+			cil_tree_print_expr(attr->datum_expr, attr->str_expr);
+
+			cil_log(CIL_INFO, "\n");
+			return;
+		}
+		case CIL_USERATTRIBUTE: {
+			struct cil_userattribute *attr = node->data;
+			cil_log(CIL_INFO, "USERATTRIBUTE: %s\n", attr->datum.name);
+			return;
+		}
 		case CIL_ROLEBOUNDS: {
 			struct cil_bounds *bnds = node->data;
 			cil_log(CIL_INFO, "ROLEBOUNDS: role: %s, bounds: %s\n", bnds->parent_str, bnds->child_str);
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 62b88d0..c2d5ce9 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -179,8 +179,8 @@
 		syntax_len = 2;
 		break;
 	case CIL_RANGE:
-		if (expr_flavor != CIL_CAT) {
-			cil_log(CIL_ERR,"Operator (%s) only valid for catset expression\n", (char*)current->data);
+		if (expr_flavor != CIL_CAT && expr_flavor != CIL_PERMISSIONX) {
+			cil_log(CIL_ERR,"Operator (%s) only valid for catset and permissionx expression\n", (char*)current->data);
 			goto exit;
 		}
 		syntax[1] = CIL_SYN_STRING;
@@ -737,16 +737,8 @@
 	int found = CIL_FALSE;
 
 	if (user->roles != NULL) {
-		cil_list_for_each(curr, user->roles) {
-			struct cil_role *userrole = curr->data;
-			if (userrole == role) {
-				break;
-			}
-		}
-
-		if (curr == NULL) {
-			cil_log(CIL_ERR, "Role %s is invalid for user %s\n",
-					ctx->role_str, ctx->user_str);
+		if (!ebitmap_get_bit(user->roles, role->value)) {
+			cil_log(CIL_ERR, "Role %s is invalid for user %s\n", ctx->role_str, ctx->user_str);
 			rc = SEPOL_ERR;
 			goto exit;
 		}
@@ -1494,13 +1486,22 @@
 	int rc = SEPOL_ERR;
 	struct cil_classpermission *cp = node->data;
 
+	if (cp->classperms == NULL) {
+		cil_log(CIL_ERR, "Classpermission %s does not have a classpermissionset at line %d of %s\n", cp->datum.name, node->line, node->path);
+		rc = SEPOL_ERR;
+		goto exit;
+	}
+
 	rc = __cil_verify_classperms(cp->classperms, &cp->datum);
 	if (rc != SEPOL_OK) {
 		cil_log(CIL_ERR, "Found circular class permissions involving the set %s at line %d of %s\n",cp->datum.name, node->line, node->path);
-		return rc;
+		goto exit;
 	}
 
-	return SEPOL_OK;
+	rc = SEPOL_OK;
+
+exit:
+	return rc;
 }
 
 struct cil_verify_map_args {
@@ -1515,12 +1516,20 @@
 	struct cil_verify_map_args *map_args = args;
 	struct cil_perm *cmp = (struct cil_perm *)d;
 
+	if (cmp->classperms == NULL) {
+		cil_log(CIL_ERR, "Map class %s does not have a classmapping for %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path);
+		map_args->rc = SEPOL_ERR;
+		goto exit;
+	}
+
 	rc = __cil_verify_classperms(cmp->classperms, &cmp->datum);
 	if (rc != SEPOL_OK) {
 		cil_log(CIL_ERR, "Found circular class permissions involving the map class %s and permission %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path);
 		map_args->rc = SEPOL_ERR;
+		goto exit;
 	}
 
+exit:
 	return SEPOL_OK;
 }
 
diff --git a/libsepol/include/sepol/policydb/avtab.h b/libsepol/include/sepol/policydb/avtab.h
index 2ea821c..d3ea84e 100644
--- a/libsepol/include/sepol/policydb/avtab.h
+++ b/libsepol/include/sepol/policydb/avtab.h
@@ -59,28 +59,29 @@
 #define AVTAB_MEMBER		0x0020
 #define AVTAB_CHANGE		0x0040
 #define AVTAB_TYPE		(AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
-#define AVTAB_OPNUM_ALLOWED	0x0100
-#define AVTAB_OPNUM_AUDITALLOW	0x0200
-#define AVTAB_OPNUM_DONTAUDIT	0x0400
-#define AVTAB_OPNUM		(AVTAB_OPNUM_ALLOWED | AVTAB_OPNUM_AUDITALLOW | AVTAB_OPNUM_DONTAUDIT)
-#define AVTAB_OPTYPE_ALLOWED	0x1000
-#define AVTAB_OPTYPE_AUDITALLOW	0x2000
-#define AVTAB_OPTYPE_DONTAUDIT	0x4000
-#define AVTAB_OPTYPE		(AVTAB_OPTYPE_ALLOWED | AVTAB_OPTYPE_AUDITALLOW | AVTAB_OPTYPE_DONTAUDIT)
-#define AVTAB_OP		(AVTAB_OPNUM | AVTAB_OPTYPE)
+#define AVTAB_XPERMS_ALLOWED	0x0100
+#define AVTAB_XPERMS_AUDITALLOW	0x0200
+#define AVTAB_XPERMS_DONTAUDIT	0x0400
+#define AVTAB_XPERMS_NEVERALLOW	0x0800
+#define AVTAB_XPERMS		(AVTAB_XPERMS_ALLOWED | AVTAB_XPERMS_AUDITALLOW | AVTAB_XPERMS_DONTAUDIT)
 #define AVTAB_ENABLED_OLD	0x80000000
 #define AVTAB_ENABLED		0x8000	/* reserved for used in cond_avtab */
 	uint16_t specified;	/* what fields are specified */
 } avtab_key_t;
 
-typedef struct avtab_operations {
-	uint8_t type;
+typedef struct avtab_extended_perms {
+
+#define AVTAB_XPERMS_IOCTLFUNCTION	0x01
+#define AVTAB_XPERMS_IOCTLDRIVER	0x02
+	/* extension of the avtab_key specified */
+	uint8_t specified;
+	uint8_t driver;
 	uint32_t perms[8];
-} avtab_operations_t;
+} avtab_extended_perms_t;
 
 typedef struct avtab_datum {
 	uint32_t data;		/* access vector or type */
-	avtab_operations_t *ops;
+	avtab_extended_perms_t *xperms;
 } avtab_datum_t;
 
 typedef struct avtab_node *avtab_ptr_t;
diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h
index 801438c..7b3508d 100644
--- a/libsepol/include/sepol/policydb/ebitmap.h
+++ b/libsepol/include/sepol/policydb/ebitmap.h
@@ -86,6 +86,7 @@
 extern int ebitmap_hamming_distance(ebitmap_t * e1, ebitmap_t * e2);
 extern int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src);
 extern int ebitmap_contains(const ebitmap_t * e1, const ebitmap_t * e2);
+extern int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2);
 extern int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit);
 extern int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value);
 extern void ebitmap_destroy(ebitmap_t * e);
diff --git a/libsepol/include/sepol/policydb/hierarchy.h b/libsepol/include/sepol/policydb/hierarchy.h
index b4eb9bc..88bc02e 100644
--- a/libsepol/include/sepol/policydb/hierarchy.h
+++ b/libsepol/include/sepol/policydb/hierarchy.h
@@ -25,11 +25,22 @@
 #ifndef _SEPOL_POLICYDB_HIERARCHY_H_
 #define _SEPOL_POLICYDB_HIERARCHY_H_
 
+#include <sepol/policydb/avtab.h>
 #include <sepol/policydb/policydb.h>
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
 
+extern int hierarchy_add_bounds(sepol_handle_t *handle, policydb_t *p);
+
+extern void bounds_destroy_bad(avtab_ptr_t cur);
+extern int bounds_check_type(sepol_handle_t *handle, policydb_t *p, uint32_t child,
+			     uint32_t parent, avtab_ptr_t *bad, int *numbad);
+
+extern int bounds_check_users(sepol_handle_t *handle, policydb_t *p);
+extern int bounds_check_roles(sepol_handle_t *handle, policydb_t *p);
+extern int bounds_check_types(sepol_handle_t *handle, policydb_t *p);
+
 extern int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p);
 
 __END_DECLS
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 1d8310c..26cec13 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -241,11 +241,19 @@
 	struct class_perm_node *next;
 } class_perm_node_t;
 
-typedef struct av_operations {
-	uint8_t type;
-	/* 256 bits of ioctl number permissions */
-	uint32_t perms[8];
-} av_operations_t;
+#define xperm_test(x, p) (1 & (p[x >> 5] >> (x & 0x1f)))
+#define xperm_set(x, p) (p[x >> 5] |= (1 << (x & 0x1f)))
+#define xperm_clear(x, p) (p[x >> 5] &= ~(1 << (x & 0x1f)))
+#define EXTENDED_PERMS_LEN 8
+
+typedef struct av_extended_perms {
+#define AVRULE_XPERMS_IOCTLFUNCTION	0x01
+#define AVRULE_XPERMS_IOCTLDRIVER	0x02
+	uint8_t specified;
+	uint8_t driver;
+	/* 256 bits of permissions */
+	uint32_t perms[EXTENDED_PERMS_LEN];
+} av_extended_perms_t;
 
 typedef struct avrule {
 /* these typedefs are almost exactly the same as those in avtab.h - they are
@@ -260,24 +268,19 @@
 #define AVRULE_MEMBER			0x0020
 #define AVRULE_CHANGE			0x0040
 #define AVRULE_TYPE       (AVRULE_TRANSITION | AVRULE_MEMBER | AVRULE_CHANGE)
-#define AVRULE_OPNUM_ALLOWED 		0x0100
-#define AVRULE_OPNUM_AUDITALLOW		0x0200
-#define AVRULE_OPNUM_DONTAUDIT		0x0400
-#define AVRULE_OPNUM         (AVRULE_OPNUM_ALLOWED | AVRULE_OPNUM_AUDITALLOW | \
-				AVRULE_OPNUM_DONTAUDIT)
-#define AVRULE_OPTYPE_ALLOWED		0x1000
-#define AVRULE_OPTYPE_AUDITALLOW	0x2000
-#define AVRULE_OPTYPE_DONTAUDIT		0x4000
-#define AVRULE_OPTYPE         (AVRULE_OPTYPE_ALLOWED | AVRULE_OPTYPE_AUDITALLOW | \
-				AVRULE_OPTYPE_DONTAUDIT)
-#define AVRULE_OP         (AVRULE_OPNUM | AVRULE_OPTYPE)
+#define AVRULE_XPERMS_ALLOWED 		0x0100
+#define AVRULE_XPERMS_AUDITALLOW	0x0200
+#define AVRULE_XPERMS_DONTAUDIT		0x0400
+#define AVRULE_XPERMS_NEVERALLOW	0x0800
+#define AVRULE_XPERMS	(AVRULE_XPERMS_ALLOWED | AVRULE_XPERMS_AUDITALLOW | \
+				AVRULE_XPERMS_DONTAUDIT | AVRULE_XPERMS_NEVERALLOW)
 	uint32_t specified;
 #define RULE_SELF 1
 	uint32_t flags;
 	type_set_t stypes;
 	type_set_t ttypes;
 	class_perm_node_t *perms;
-	av_operations_t * ops;
+	av_extended_perms_t *xperms;
 	unsigned long line;	/* line number from policy.conf where
 				 * this rule originated  */
 	/* source file name and line number (e.g. .te file) */
@@ -652,7 +655,7 @@
 extern void level_datum_destroy(level_datum_t * x);
 extern void cat_datum_init(cat_datum_t * x);
 extern void cat_datum_destroy(cat_datum_t * x);
-
+extern int check_assertion(policydb_t *p, avrule_t *avrule);
 extern int check_assertions(sepol_handle_t * handle,
 			    policydb_t * p, avrule_t * avrules);
 
@@ -709,11 +712,11 @@
 #define POLICYDB_VERSION_DEFAULT_TYPE	28
 #define POLICYDB_VERSION_CONSTRAINT_NAMES	29
 #define POLICYDB_VERSION_XEN_DEVICETREE		30 /* Xen-specific */
-#define POLICYDB_VERSION_IOCTL_OPERATIONS	30 /* Linux-specific */
+#define POLICYDB_VERSION_XPERMS_IOCTL	30 /* Linux-specific */
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_IOCTL_OPERATIONS
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_XPERMS_IOCTL
 
 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE		4
diff --git a/libsepol/include/sepol/policydb/util.h b/libsepol/include/sepol/policydb/util.h
index ef1c90d..fa12661 100644
--- a/libsepol/include/sepol/policydb/util.h
+++ b/libsepol/include/sepol/policydb/util.h
@@ -32,5 +32,13 @@
 extern char *sepol_av_to_string(policydb_t * policydbp, uint32_t tclass,
 				sepol_access_vector_t av);
 
+char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms);
+
+/*
+ * The tokenize function may be used to
+ * replace sscanf
+ */
+extern int tokenize(char *line_buf, char delim, int num_args, ...);
+
 __END_DECLS
 #endif
diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c
index c335968..5aec658 100644
--- a/libsepol/src/assertion.c
+++ b/libsepol/src/assertion.c
@@ -1,8 +1,8 @@
 /* Authors: Joshua Brindle <jbrindle@tresys.com>
- *              
- * Assertion checker for avtab entries, taken from 
+ *
+ * Assertion checker for avtab entries, taken from
  * checkpolicy.c by Stephen Smalley <sds@tycho.nsa.gov>
- *              
+ *
  * Copyright (C) 2005 Tresys Technology, LLC
  *
  *  This library is free software; you can redistribute it and/or
@@ -25,13 +25,20 @@
 #include <sepol/policydb/expand.h>
 #include <sepol/policydb/util.h>
 
+#include "private.h"
 #include "debug.h"
 
-static void report_failure(sepol_handle_t *handle, policydb_t *p,
-			   const avrule_t * avrule,
+struct avtab_match_args {
+	sepol_handle_t *handle;
+	policydb_t *p;
+	avrule_t *avrule;
+	avtab_t *avtab;
+	unsigned long errors;
+};
+
+static void report_failure(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule,
 			   unsigned int stype, unsigned int ttype,
-			   const class_perm_node_t *curperm,
-			   const avtab_ptr_t node)
+			   const class_perm_node_t *curperm, uint32_t perms)
 {
 	if (avrule->source_filename) {
 		ERR(handle, "neverallow on line %lu of %s (or line %lu of policy.conf) violated by allow %s %s:%s {%s };",
@@ -39,69 +46,386 @@
 		    p->p_type_val_to_name[stype],
 		    p->p_type_val_to_name[ttype],
 		    p->p_class_val_to_name[curperm->tclass - 1],
-		    sepol_av_to_string(p, curperm->tclass,
-				       node->datum.data & curperm->data));
+		    sepol_av_to_string(p, curperm->tclass, perms));
 	} else if (avrule->line) {
 		ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };",
 		    avrule->line, p->p_type_val_to_name[stype],
 		    p->p_type_val_to_name[ttype],
 		    p->p_class_val_to_name[curperm->tclass - 1],
-		    sepol_av_to_string(p, curperm->tclass,
-				       node->datum.data & curperm->data));
+		    sepol_av_to_string(p, curperm->tclass, perms));
 	} else {
 		ERR(handle, "neverallow violated by allow %s %s:%s {%s };",
 		    p->p_type_val_to_name[stype],
 		    p->p_type_val_to_name[ttype],
 		    p->p_class_val_to_name[curperm->tclass - 1],
-		    sepol_av_to_string(p, curperm->tclass,
-				       node->datum.data & curperm->data));
+		    sepol_av_to_string(p, curperm->tclass, perms));
 	}
 }
 
-static unsigned long check_assertion_helper(sepol_handle_t * handle,
-				  policydb_t * p,
-				  avtab_t * te_avtab, avtab_t * te_cond_avtab,
-				  unsigned int stype, unsigned int ttype,
-				  const avrule_t * avrule)
+static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, uint32_t data)
 {
-	avtab_key_t avkey;
-	avtab_ptr_t node;
-	class_perm_node_t *curperm;
-	unsigned long errors = 0;
-
-	for (curperm = avrule->perms; curperm != NULL; curperm = curperm->next) {
-		avkey.source_type = stype + 1;
-		avkey.target_type = ttype + 1;
-		avkey.target_class = curperm->tclass;
-		avkey.specified = AVTAB_ALLOWED;
-		for (node = avtab_search_node(te_avtab, &avkey);
-		     node != NULL;
-		     node = avtab_search_node_next(node, avkey.specified)) {
-			if (node->datum.data & curperm->data) {
-				report_failure(handle, p, avrule, stype, ttype, curperm, node);
-				errors++;
-			}
+	for (; cp; cp = cp->next) {
+		if ((cp->tclass == class) && (cp->data & data)) {
+			break;
 		}
-		for (node = avtab_search_node(te_cond_avtab, &avkey);
-		     node != NULL;
-		     node = avtab_search_node_next(node, avkey.specified)) {
-			if (node->datum.data & curperm->data) {
-				report_failure(handle, p, avrule, stype, ttype, curperm, node);
-				errors++;
+	}
+	if (!cp)
+		return 0;
+
+	return 1;
+}
+
+static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) {
+	size_t i;
+	for (i = 0; i < EXTENDED_PERMS_LEN; i++) {
+		if (perms1[i] & perms2[i])
+			return 1;
+	}
+
+	return 0;
+}
+
+static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow)
+{
+	int rc = 0;
+	if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+		if (neverallow->driver == allow->driver)
+			rc = extended_permissions_and(neverallow->perms, allow->perms);
+	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+		rc = xperm_test(neverallow->driver, allow->perms);
+	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+		rc = xperm_test(allow->driver, neverallow->perms);
+	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+		rc = extended_permissions_and(neverallow->perms, allow->perms);
+	}
+
+	return rc;
+}
+
+/* Compute which allowed extended permissions violate the neverallow rule */
+static void extended_permissions_violated(avtab_extended_perms_t *result,
+					av_extended_perms_t *neverallow,
+					avtab_extended_perms_t *allow)
+{
+	size_t i;
+	if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+		result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+		result->driver = allow->driver;
+		for (i = 0; i < EXTENDED_PERMS_LEN; i++)
+			result->perms[i] = neverallow->perms[i] & allow->perms[i];
+	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+		result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+		result->driver = neverallow->driver;
+		memcpy(result->perms, neverallow->perms, sizeof(result->perms));
+	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
+		result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
+		result->driver = allow->driver;
+		memcpy(result->perms, allow->perms, sizeof(result->perms));
+	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
+			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
+		result->specified = AVTAB_XPERMS_IOCTLDRIVER;
+		for (i = 0; i < EXTENDED_PERMS_LEN; i++)
+			result->perms[i] = neverallow->perms[i] & allow->perms[i];
+	}
+}
+
+/* Same scenarios of interest as check_assertion_extended_permissions */
+static int report_assertion_extended_permissions(sepol_handle_t *handle,
+				policydb_t *p, const avrule_t *avrule,
+				unsigned int stype, unsigned int ttype,
+				const class_perm_node_t *curperm, uint32_t perms,
+				avtab_key_t *k, avtab_t *avtab)
+{
+	avtab_ptr_t node;
+	avtab_key_t tmp_key;
+	avtab_extended_perms_t *xperms;
+	avtab_extended_perms_t error;
+	int rc = 1;
+	int ret = 0;
+
+	memcpy(&tmp_key, k, sizeof(avtab_key_t));
+	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
+
+	for (node = avtab_search_node(avtab, &tmp_key);
+	     node;
+	     node = avtab_search_node_next(node, tmp_key.specified)) {
+		xperms = node->datum.xperms;
+		if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+				&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+			continue;
+
+		rc = check_extended_permissions(avrule->xperms, xperms);
+		/* failure on the extended permission check_extended_permissionss */
+		if (rc) {
+			extended_permissions_violated(&error, avrule->xperms, xperms);
+			ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
+					"allowxperm %s %s:%s %s;",
+					avrule->source_line, avrule->source_filename, avrule->line,
+					p->p_type_val_to_name[stype],
+					p->p_type_val_to_name[ttype],
+					p->p_class_val_to_name[curperm->tclass - 1],
+					sepol_extended_perms_to_string(&error));
+
+			rc = 0;
+			ret++;
+		}
+
+	}
+
+	/* failure on the regular permissions */
+	if (rc) {
+		ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
+				"allow %s %s:%s {%s };",
+				avrule->source_line, avrule->source_filename, avrule->line,
+				p->p_type_val_to_name[stype],
+				p->p_type_val_to_name[ttype],
+				p->p_class_val_to_name[curperm->tclass - 1],
+				sepol_av_to_string(p, curperm->tclass, perms));
+		ret++;
+
+	}
+
+	return ret;
+}
+
+static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args)
+{
+	int rc = 0;
+	struct avtab_match_args *a = (struct avtab_match_args *)args;
+	sepol_handle_t *handle = a->handle;
+	policydb_t *p = a->p;
+	avtab_t *avtab = a->avtab;
+	avrule_t *avrule = a->avrule;
+	class_perm_node_t *cp;
+	uint32_t perms;
+	ebitmap_t src_matches, tgt_matches, matches;
+	ebitmap_node_t *snode, *tnode;
+	unsigned int i, j;
+
+	if (k->specified != AVTAB_ALLOWED)
+		return 0;
+
+	if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
+		return 0;
+
+	ebitmap_init(&src_matches);
+	ebitmap_init(&tgt_matches);
+	ebitmap_init(&matches);
+
+	rc = ebitmap_and(&src_matches, &avrule->stypes.types,
+			 &p->attr_type_map[k->source_type - 1]);
+	if (rc)
+		goto oom;
+
+	if (ebitmap_length(&src_matches) == 0)
+		goto exit;
+
+	if (avrule->flags == RULE_SELF) {
+		rc = ebitmap_and(&matches, &p->attr_type_map[k->source_type - 1], &p->attr_type_map[k->target_type - 1]);
+		if (rc)
+			goto oom;
+		rc = ebitmap_and(&tgt_matches, &avrule->stypes.types, &matches);
+		if (rc)
+			goto oom;
+	} else {
+		rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
+		if (rc)
+			goto oom;
+	}
+
+	if (ebitmap_length(&tgt_matches) == 0)
+		goto exit;
+
+	for (cp = avrule->perms; cp; cp = cp->next) {
+
+		perms = cp->data & d->data;
+		if ((cp->tclass != k->target_class) || !perms) {
+			continue;
+		}
+
+		ebitmap_for_each_bit(&src_matches, snode, i) {
+			if (!ebitmap_node_get_bit(snode, i))
+				continue;
+			ebitmap_for_each_bit(&tgt_matches, tnode, j) {
+				if (!ebitmap_node_get_bit(tnode, j))
+					continue;
+
+				if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
+					a->errors += report_assertion_extended_permissions(handle,p, avrule,
+											i, j, cp, perms, k, avtab);
+				} else {
+					a->errors++;
+					report_failure(handle, p, avrule, i, j, cp, perms);
+				}
 			}
 		}
 	}
+	goto exit;
 
-	return errors;
+oom:
+	ERR(NULL, "Out of memory - unable to check neverallows");
+
+exit:
+	ebitmap_destroy(&src_matches);
+	ebitmap_destroy(&tgt_matches);
+	ebitmap_destroy(&matches);
+	return rc;
+}
+
+int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
+{
+	int rc;
+	struct avtab_match_args args;
+
+	args.handle = handle;
+	args.p = p;
+	args.avrule = avrule;
+	args.errors = 0;
+
+	rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args);
+	if (rc)
+		goto oom;
+
+	rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args);
+	if (rc)
+		goto oom;
+
+	return args.errors;
+
+oom:
+	return rc;
+}
+
+/*
+ * If the ioctl permission is granted in check_assertion_avtab_match for the
+ * source/target/class matching the current avrule neverallow, a lookup is
+ * performed to determine if extended permissions exist for the source/target/class.
+ *
+ * Four scenarios of interest:
+ * 1. PASS - the ioctl permission is not granted for this source/target/class
+ *    This case is handled in check_assertion_avtab_match
+ * 2. PASS - The ioctl permission is granted AND the extended permission
+ *    is NOT granted
+ * 3. FAIL - The ioctl permission is granted AND no extended permissions
+ *    exist
+ * 4. FAIL - The ioctl permission is granted AND the extended permission is
+ *    granted
+ */
+static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
+						avtab_key_t *k)
+{
+	avtab_ptr_t node;
+	avtab_key_t tmp_key;
+	avtab_extended_perms_t *xperms;
+	av_extended_perms_t *neverallow_xperms = avrule->xperms;
+	int rc = 1;
+
+	memcpy(&tmp_key, k, sizeof(avtab_key_t));
+	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
+
+	for (node = avtab_search_node(avtab, &tmp_key);
+	     node;
+	     node = avtab_search_node_next(node, tmp_key.specified)) {
+		xperms = node->datum.xperms;
+		if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+				&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+			continue;
+
+		rc = check_extended_permissions(neverallow_xperms, xperms);
+		if (rc)
+			break;
+	}
+
+	return rc;
+}
+
+
+static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
+{
+	int rc;
+	struct avtab_match_args *a = (struct avtab_match_args *)args;
+	policydb_t *p = a->p;
+	avrule_t *avrule = a->avrule;
+	avtab_t *avtab = a->avtab;
+
+	if (k->specified != AVTAB_ALLOWED)
+		goto exit;
+
+	if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
+		goto exit;
+
+	rc = ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
+	if (rc == 0)
+		goto exit;
+
+	if (avrule->flags == RULE_SELF) {
+		/* If the neverallow uses SELF, then it is not enough that the
+		 * neverallow's source matches the src and tgt of the rule being checked.
+		 * It must match the same thing in the src and tgt, so AND the source
+		 * and target together and check for a match on the result.
+		 */
+		ebitmap_t match;
+		rc = ebitmap_and(&match, &p->attr_type_map[k->source_type - 1], &p->attr_type_map[k->target_type - 1] );
+		if (rc) {
+			ebitmap_destroy(&match);
+			goto oom;
+		}
+		rc = ebitmap_match_any(&avrule->stypes.types, &match);
+		ebitmap_destroy(&match);
+	} else {
+		rc = ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
+	}
+	if (rc == 0)
+		goto exit;
+
+	if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
+		rc = check_assertion_extended_permissions(avrule, avtab, k);
+		if (rc == 0)
+			goto exit;
+	}
+	return 1;
+
+exit:
+	return 0;
+
+oom:
+	ERR(NULL, "Out of memory - unable to check neverallows");
+	return rc;
+}
+
+int check_assertion(policydb_t *p, avrule_t *avrule)
+{
+	int rc;
+	struct avtab_match_args args;
+
+	args.handle = NULL;
+	args.p = p;
+	args.avrule = avrule;
+	args.errors = 0;
+	args.avtab = &p->te_avtab;
+
+	rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args);
+
+	if (rc == 0) {
+		args.avtab = &p->te_cond_avtab;
+		rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args);
+	}
+
+	return rc;
 }
 
 int check_assertions(sepol_handle_t * handle, policydb_t * p,
 		     avrule_t * avrules)
 {
+	int rc;
 	avrule_t *a;
-	avtab_t te_avtab, te_cond_avtab;
-	ebitmap_node_t *snode, *tnode;
-	unsigned int i, j;
 	unsigned long errors = 0;
 
 	if (!avrules) {
@@ -111,54 +435,22 @@
 		return 0;
 	}
 
-	if (avrules) {
-		if (avtab_init(&te_avtab))
-			goto oom;
-		if (avtab_init(&te_cond_avtab)) {
-			avtab_destroy(&te_avtab);
-			goto oom;
-		}
-		if (expand_avtab(p, &p->te_avtab, &te_avtab) ||
-		    expand_avtab(p, &p->te_cond_avtab, &te_cond_avtab)) {
-			avtab_destroy(&te_avtab);
-			avtab_destroy(&te_cond_avtab);
-			goto oom;
-		}
-	}
-
 	for (a = avrules; a != NULL; a = a->next) {
-		ebitmap_t *stypes = &a->stypes.types;
-		ebitmap_t *ttypes = &a->ttypes.types;
-
-		if (!(a->specified & AVRULE_NEVERALLOW))
+		if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)))
 			continue;
-
-		ebitmap_for_each_bit(stypes, snode, i) {
-			if (!ebitmap_node_get_bit(snode, i))
-				continue;
-			if (a->flags & RULE_SELF) {
-				errors += check_assertion_helper
-				    (handle, p, &te_avtab, &te_cond_avtab, i, i,
-				     a);
+		rc = check_assertion(p, a);
+		if (rc) {
+			rc = report_assertion_failures(handle, p, a);
+			if (rc < 0) {
+				ERR(handle, "Error occurred while checking neverallows");
+				return -1;
 			}
-			ebitmap_for_each_bit(ttypes, tnode, j) {
-				if (!ebitmap_node_get_bit(tnode, j))
-					continue;
-				errors += check_assertion_helper
-				    (handle, p, &te_avtab, &te_cond_avtab, i, j,
-				     a);
-			}
+			errors += rc;
 		}
 	}
 
 	if (errors)
 		ERR(handle, "%lu neverallow failures occurred", errors);
 
-	avtab_destroy(&te_avtab);
-	avtab_destroy(&te_cond_avtab);
 	return errors ? -1 : 0;
-
-      oom:
-	ERR(handle, "Out of memory - unable to check neverallows");
-	return -1;
 }
diff --git a/libsepol/src/avtab.c b/libsepol/src/avtab.c
index d3745fe..c32fda1 100644
--- a/libsepol/src/avtab.c
+++ b/libsepol/src/avtab.c
@@ -93,7 +93,7 @@
 		  avtab_datum_t * datum)
 {
 	avtab_ptr_t newnode;
-	avtab_operations_t *ops;
+	avtab_extended_perms_t *xperms;
 
 	newnode = (avtab_ptr_t) malloc(sizeof(struct avtab_node));
 	if (newnode == NULL)
@@ -101,16 +101,16 @@
 	memset(newnode, 0, sizeof(struct avtab_node));
 	newnode->key = *key;
 
-	if (key->specified & AVTAB_OP) {
-		ops = calloc(1, sizeof(avtab_operations_t));
-		if (ops == NULL) {
+	if (key->specified & AVTAB_XPERMS) {
+		xperms = calloc(1, sizeof(avtab_extended_perms_t));
+		if (xperms == NULL) {
 			free(newnode);
 			return NULL;
 		}
-		if (datum->ops) /* else caller populates ops*/
-			*ops = *(datum->ops);
+		if (datum->xperms) /* else caller populates xperms */
+			*xperms = *(datum->xperms);
 
-		newnode->datum.ops = ops;
+		newnode->datum.xperms = xperms;
 	} else {
 		newnode->datum = *datum;
 	}
@@ -144,7 +144,8 @@
 		    key->target_type == cur->key.target_type &&
 		    key->target_class == cur->key.target_class &&
 		    (specified & cur->key.specified)) {
-			if (specified & AVTAB_OPNUM)
+			/* Extended permissions are not necessarily unique */
+			if (specified & AVTAB_XPERMS)
 				break;
 			return SEPOL_EEXIST;
 		}
@@ -308,6 +309,9 @@
 	for (i = 0; i < h->nslot; i++) {
 		cur = h->htable[i];
 		while (cur != NULL) {
+			if (cur->key.specified & AVTAB_XPERMS) {
+				free(cur->datum.xperms);
+			}
 			temp = cur;
 			cur = cur->next;
 			free(temp);
@@ -416,12 +420,9 @@
 	AVTAB_TRANSITION,
 	AVTAB_CHANGE,
 	AVTAB_MEMBER,
-	AVTAB_OPNUM_ALLOWED,
-	AVTAB_OPNUM_AUDITALLOW,
-	AVTAB_OPNUM_DONTAUDIT,
-	AVTAB_OPTYPE_ALLOWED,
-	AVTAB_OPTYPE_AUDITALLOW,
-	AVTAB_OPTYPE_DONTAUDIT
+	AVTAB_XPERMS_ALLOWED,
+	AVTAB_XPERMS_AUDITALLOW,
+	AVTAB_XPERMS_DONTAUDIT
 };
 
 int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
@@ -433,14 +434,14 @@
 	uint32_t buf32[8], items, items2, val;
 	avtab_key_t key;
 	avtab_datum_t datum;
-	avtab_operations_t ops;
+	avtab_extended_perms_t xperms;
 	unsigned set;
 	unsigned int i;
 	int rc;
 
 	memset(&key, 0, sizeof(avtab_key_t));
 	memset(&datum, 0, sizeof(avtab_datum_t));
-	memset(&ops, 0, sizeof(avtab_operations_t));
+	memset(&xperms, 0, sizeof(avtab_extended_perms_t));
 
 	if (vers < POLICYDB_VERSION_AVTAB) {
 		rc = next_entry(buf32, fp, sizeof(uint32_t));
@@ -533,26 +534,32 @@
 		return -1;
 	}
 
-	if ((vers < POLICYDB_VERSION_IOCTL_OPERATIONS) &&
-			(key.specified & AVTAB_OP)) {
-		ERR(fp->handle, "policy version %u does not support ioctl "
-				"operation rules and one was specified\n", vers);
+	if ((vers < POLICYDB_VERSION_XPERMS_IOCTL) &&
+			(key.specified & AVTAB_XPERMS)) {
+		ERR(fp->handle, "policy version %u does not support extended "
+				"permissions rules and one was specified\n", vers);
 		return -1;
-	} else if (key.specified & AVTAB_OP) {
+	} else if (key.specified & AVTAB_XPERMS) {
 		rc = next_entry(&buf8, fp, sizeof(uint8_t));
 		if (rc < 0) {
 			ERR(fp->handle, "truncated entry");
 			return -1;
 		}
-		ops.type = buf8;
+		xperms.specified = buf8;
+		rc = next_entry(&buf8, fp, sizeof(uint8_t));
+		if (rc < 0) {
+			ERR(fp->handle, "truncated entry");
+			return -1;
+		}
+		xperms.driver = buf8;
 		rc = next_entry(buf32, fp, sizeof(uint32_t)*8);
 		if (rc < 0) {
 			ERR(fp->handle, "truncated entry");
 			return -1;
 		}
-		for (i = 0; i < ARRAY_SIZE(ops.perms); i++)
-			ops.perms[i] = le32_to_cpu(buf32[i]);
-		datum.ops = &ops;
+		for (i = 0; i < ARRAY_SIZE(xperms.perms); i++)
+			xperms.perms[i] = le32_to_cpu(buf32[i]);
+		datum.xperms = &xperms;
 	} else {
 		rc = next_entry(buf32, fp, sizeof(uint32_t));
 		if (rc < 0) {
diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
index be6b591..58f2fc4 100644
--- a/libsepol/src/ebitmap.c
+++ b/libsepol/src/ebitmap.c
@@ -224,6 +224,28 @@
 	return 1;
 }
 
+int ebitmap_match_any(const ebitmap_t *e1, const ebitmap_t *e2)
+{
+	ebitmap_node_t *n1 = e1->node;
+	ebitmap_node_t *n2 = e2->node;
+
+	while (n1 && n2) {
+		if (n1->startbit < n2->startbit) {
+			n1 = n1->next;
+		} else if (n2->startbit < n1->startbit) {
+			n2 = n2->next;
+		} else {
+			if (n1->map & n2->map) {
+				return 1;
+			}
+			n1 = n1->next;
+			n2 = n2->next;
+		}
+	}
+
+	return 0;
+}
+
 int ebitmap_get_bit(const ebitmap_t * e, unsigned int bit)
 {
 	ebitmap_node_t *n;
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
index b999890..9047c6d 100644
--- a/libsepol/src/expand.c
+++ b/libsepol/src/expand.c
@@ -1604,24 +1604,25 @@
 static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,
 				   avtab_t * avtab, avtab_key_t * key,
 				   cond_av_list_t ** cond,
-				   av_operations_t *operations)
+				   av_extended_perms_t *xperms)
 {
 	avtab_ptr_t node;
 	avtab_datum_t avdatum;
 	cond_av_list_t *nl;
-	int type_match = 0;
+	int match = 0;
 
-	/* AVTAB_OPNUM entries are not necessarily unique */
-	if (key->specified & AVTAB_OPNUM) {
+	/* AVTAB_XPERMS entries are not necessarily unique */
+	if (key->specified & AVTAB_XPERMS) {
 		node = avtab_search_node(avtab, key);
 		while (node) {
-			if (node->datum.ops->type == operations->type) {
-				type_match = 1;
+			if ((node->datum.xperms->specified == xperms->specified) &&
+				(node->datum.xperms->driver == xperms->driver)) {
+				match = 1;
 				break;
 			}
 			node = avtab_search_node_next(node, key->specified);
 		}
-		if (!type_match)
+		if (!match)
 			node = NULL;
 	} else {
 		node = avtab_search_node(avtab, key);
@@ -1780,11 +1781,11 @@
 				cond_av_list_t ** cond,
 				uint32_t stype, uint32_t ttype,
 				class_perm_node_t * perms, avtab_t * avtab,
-				int enabled, av_operations_t *operations)
+				int enabled, av_extended_perms_t *extended_perms)
 {
 	avtab_key_t avkey;
 	avtab_datum_t *avdatump;
-	avtab_operations_t *ops;
+	avtab_extended_perms_t *xperms;
 	avtab_ptr_t node;
 	class_perm_node_t *cur;
 	uint32_t spec = 0;
@@ -1802,22 +1803,14 @@
 		spec = AVTAB_AUDITDENY;
 	} else if (specified & AVRULE_NEVERALLOW) {
 		spec = AVTAB_NEVERALLOW;
-	} else if (specified & AVRULE_OPNUM_ALLOWED) {
-		spec = AVTAB_OPNUM_ALLOWED;
-	} else if (specified & AVRULE_OPNUM_AUDITALLOW) {
-		spec = AVTAB_OPNUM_AUDITALLOW;
-	} else if (specified & AVRULE_OPNUM_DONTAUDIT) {
+	} else if (specified & AVRULE_XPERMS_ALLOWED) {
+		spec = AVTAB_XPERMS_ALLOWED;
+	} else if (specified & AVRULE_XPERMS_AUDITALLOW) {
+		spec = AVTAB_XPERMS_AUDITALLOW;
+	} else if (specified & AVRULE_XPERMS_DONTAUDIT) {
 		if (handle && handle->disable_dontaudit)
 			return EXPAND_RULE_SUCCESS;
-		spec = AVTAB_OPNUM_DONTAUDIT;
-	} else if (specified & AVRULE_OPTYPE_ALLOWED) {
-		spec = AVTAB_OPTYPE_ALLOWED;
-	} else if (specified & AVRULE_OPTYPE_AUDITALLOW) {
-		spec = AVTAB_OPTYPE_AUDITALLOW;
-	} else if (specified & AVRULE_OPTYPE_DONTAUDIT) {
-		if (handle && handle->disable_dontaudit)
-			return EXPAND_RULE_SUCCESS;
-		spec = AVTAB_OPTYPE_DONTAUDIT;
+		spec = AVTAB_XPERMS_DONTAUDIT;
 	} else {
 		assert(0);	/* unreachable */
 	}
@@ -1829,7 +1822,7 @@
 		avkey.target_class = cur->tclass;
 		avkey.specified = spec;
 
-		node = find_avtab_node(handle, avtab, &avkey, cond, operations);
+		node = find_avtab_node(handle, avtab, &avkey, cond, extended_perms);
 		if (!node)
 			return EXPAND_RULE_ERROR;
 		if (enabled) {
@@ -1859,20 +1852,21 @@
 				avdatump->data &= ~cur->data;
 			else
 				avdatump->data = ~cur->data;
-		} else if (specified & AVRULE_OP) {
-			if (!avdatump->ops) {
-				ops = (avtab_operations_t *)
-					calloc(1, sizeof(avtab_operations_t));
-				if (!ops) {
+		} else if (specified & AVRULE_XPERMS) {
+			if (!avdatump->xperms) {
+				xperms = (avtab_extended_perms_t *)
+					calloc(1, sizeof(avtab_extended_perms_t));
+				if (!xperms) {
 					ERR(handle, "Out of memory!");
 					return -1;
 				}
-				node->datum.ops = ops;
+				node->datum.xperms = xperms;
 			}
-			node->datum.ops->type = operations->type;
-			for (i = 0; i < ARRAY_SIZE(operations->perms); i++) {
-				node->datum.ops->perms[i] |= operations->perms[i];
-			}
+			node->datum.xperms->specified = extended_perms->specified;
+			node->datum.xperms->driver = extended_perms->driver;
+
+			for (i = 0; i < ARRAY_SIZE(xperms->perms); i++)
+				node->datum.xperms->perms[i] |= extended_perms->perms[i];
 		} else {
 			assert(0);	/* should never occur */
 		}
@@ -1897,10 +1891,10 @@
 		if (!ebitmap_node_get_bit(snode, i))
 			continue;
 		if (source_rule->flags & RULE_SELF) {
-			if (source_rule->specified & (AVRULE_AV | AVRULE_OP)) {
+			if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) {
 				retval = expand_avrule_helper(handle, source_rule->specified,
 							      cond, i, i, source_rule->perms,
-							      dest_avtab, enabled, source_rule->ops);
+							      dest_avtab, enabled, source_rule->xperms);
 				if (retval != EXPAND_RULE_SUCCESS)
 					return retval;
 			} else {
@@ -1915,10 +1909,10 @@
 		ebitmap_for_each_bit(ttypes, tnode, j) {
 			if (!ebitmap_node_get_bit(tnode, j))
 				continue;
-			if (source_rule->specified & (AVRULE_AV | AVRULE_OP)) {
+			if (source_rule->specified & (AVRULE_AV | AVRULE_XPERMS)) {
 				retval = expand_avrule_helper(handle, source_rule->specified,
 							      cond, i, j, source_rule->perms,
-							      dest_avtab, enabled, source_rule->ops);
+							      dest_avtab, enabled, source_rule->xperms);
 				if (retval != EXPAND_RULE_SUCCESS)
 					return retval;
 			} else {
@@ -1954,6 +1948,8 @@
 
 	if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW)
 		return EXPAND_RULE_SUCCESS;
+	if (source_rule->specified & AVRULE_XPERMS_NEVERALLOW)
+		return EXPAND_RULE_SUCCESS;
 
 	ebitmap_init(&stypes);
 	ebitmap_init(&ttypes);
@@ -2317,25 +2313,33 @@
 	policydb_t *p = state->out;
 	unsigned int i;
 	ebitmap_node_t *tnode;
+	int value;
 
 	type = (type_datum_t *) datum;
+	value = type->s.value;
+
 	if (type->flavor == TYPE_ATTRIB) {
-		if (ebitmap_cpy(&p->attr_type_map[type->s.value - 1],
-				&type->types)) {
-			ERR(state->handle, "Out of memory!");
-			return -1;
+		if (ebitmap_cpy(&p->attr_type_map[value - 1], &type->types)) {
+			goto oom;
 		}
 		ebitmap_for_each_bit(&type->types, tnode, i) {
 			if (!ebitmap_node_get_bit(tnode, i))
 				continue;
-			if (ebitmap_set_bit(&p->type_attr_map[i],
-					    type->s.value - 1, 1)) {
-				ERR(state->handle, "Out of memory!");
-				return -1;
+			if (ebitmap_set_bit(&p->type_attr_map[i], value - 1, 1)) {
+				goto oom;
 			}
 		}
+	} else {
+		if (ebitmap_set_bit(&p->attr_type_map[value - 1], value - 1, 1)) {
+			goto oom;
+		}
 	}
+
 	return 0;
+
+oom:
+	ERR(state->handle, "Out of memory!");
+	return -1;
 }
 
 /* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy.
@@ -2376,7 +2380,8 @@
 	int retval;
 	ebitmap_t stypes, ttypes;
 
-	if (source_rule->specified & AVRULE_NEVERALLOW)
+	if ((source_rule->specified & AVRULE_NEVERALLOW)
+		|| (source_rule->specified & AVRULE_XPERMS_NEVERALLOW))
 		return 1;
 
 	ebitmap_init(&stypes);
@@ -2590,6 +2595,7 @@
 	ebitmap_t stypes, ttypes;
 	avrule_t *avrule;
 	class_perm_node_t *cur_perm, *new_perm, *tail_perm;
+	av_extended_perms_t *xperms = NULL;
 
 	ebitmap_init(&stypes);
 	ebitmap_init(&ttypes);
@@ -2606,7 +2612,7 @@
 		return -1;
 
 	avrule_init(avrule);
-	avrule->specified = AVRULE_NEVERALLOW;
+	avrule->specified = source_rule->specified;
 	avrule->line = source_rule->line;
 	avrule->flags = source_rule->flags;
 	avrule->source_line = source_rule->source_line;
@@ -2645,6 +2651,15 @@
 		cur_perm = cur_perm->next;
 	}
 
+	/* copy over extended permissions */
+	if (source_rule->xperms) {
+		xperms = calloc(1, sizeof(av_extended_perms_t));
+		if (!xperms)
+			goto err;
+		memcpy(xperms, source_rule->xperms, sizeof(av_extended_perms_t));
+		avrule->xperms = xperms;
+	}
+
 	/* just prepend the avrule to the first branch; it'll never be
 	   written to disk */
 	if (!dest_pol->global->branch_list->avrules)
@@ -2670,6 +2685,7 @@
 		free(cur_perm);
 		cur_perm = tail_perm;
 	}
+	free(xperms);
 	free(avrule);
 	return -1;
 }
@@ -2722,16 +2738,15 @@
 		cur_avrule = decl->avrules;
 		while (cur_avrule != NULL) {
 			if (!(state->expand_neverallow)
-			    && cur_avrule->specified & AVRULE_NEVERALLOW) {
+			    && cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)) {
 				/* copy this over directly so that assertions are checked later */
 				if (copy_neverallow
 				    (state->out, state->typemap, cur_avrule))
 					ERR(state->handle,
 					    "Error while copying neverallow.");
 			} else {
-				if (cur_avrule->specified & AVRULE_NEVERALLOW) {
+				if (cur_avrule->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW))
 					state->out->unsupported_format = 1;
-				}
 				if (convert_and_expand_rule
 				    (state->handle, state->out, state->typemap,
 				     cur_avrule, &state->out->te_avtab, NULL,
@@ -3155,24 +3170,25 @@
 {
 	avtab_ptr_t node;
 	avtab_datum_t *avd;
-	avtab_operations_t *ops;
+	avtab_extended_perms_t *xperms;
 	unsigned int i;
-	unsigned int type_match = 0;
+	unsigned int match = 0;
 
-	if (k->specified & AVTAB_OPNUM) {
+	if (k->specified & AVTAB_XPERMS) {
 		/*
-		 * AVTAB_OPNUM entries are not necessarily unique.
-		 * find node with matching ops->type
+		 * AVTAB_XPERMS entries are not necessarily unique.
+		 * find node with matching xperms
 		 */
 		node = avtab_search_node(a, k);
 		while (node) {
-			if (node->datum.ops->type == d->ops->type) {
-				type_match = 1;
+			if ((node->datum.xperms->specified == d->xperms->specified) &&
+				(node->datum.xperms->driver == d->xperms->driver)) {
+				match = 1;
 				break;
 			}
 			node = avtab_search_node_next(node, k->specified);
 		}
-		if (!type_match)
+		if (!match)
 			node = NULL;
 	} else {
 		node = avtab_search_node(a, k);
@@ -3189,7 +3205,7 @@
 	}
 
 	avd = &node->datum;
-	ops = node->datum.ops;
+	xperms = node->datum.xperms;
 	switch (k->specified & ~AVTAB_ENABLED) {
 	case AVTAB_ALLOWED:
 	case AVTAB_AUDITALLOW:
@@ -3198,14 +3214,11 @@
 	case AVTAB_AUDITDENY:
 		avd->data &= d->data;
 		break;
-	case AVTAB_OPNUM_ALLOWED:
-	case AVTAB_OPNUM_AUDITALLOW:
-	case AVTAB_OPNUM_DONTAUDIT:
-	case AVTAB_OPTYPE_ALLOWED:
-	case AVTAB_OPTYPE_AUDITALLOW:
-	case AVTAB_OPTYPE_DONTAUDIT:
-		for (i = 0; i < ARRAY_SIZE(ops->perms); i++)
-			ops->perms[i] |= d->ops->perms[i];
+	case AVTAB_XPERMS_ALLOWED:
+	case AVTAB_XPERMS_AUDITALLOW:
+	case AVTAB_XPERMS_DONTAUDIT:
+		for (i = 0; i < ARRAY_SIZE(xperms->perms); i++)
+			xperms->perms[i] |= d->xperms->perms[i];
 		break;
 	default:
 		ERR(NULL, "Type conflict!");
diff --git a/libsepol/src/hierarchy.c b/libsepol/src/hierarchy.c
index d787a64..f6c5fae 100644
--- a/libsepol/src/hierarchy.c
+++ b/libsepol/src/hierarchy.c
@@ -37,466 +37,702 @@
 
 #include "debug.h"
 
-typedef struct hierarchy_args {
-	policydb_t *p;
-	avtab_t *expa;		/* expanded avtab */
-	/* This tells check_avtab_hierarchy to check this list in addition to the unconditional avtab */
-	cond_av_list_t *opt_cond_list;
-	sepol_handle_t *handle;
-	int numerr;
-} hierarchy_args_t;
+#define BOUNDS_AVTAB_SIZE 1024
 
-/*
- * find_parent_(type|role|user)
- *
- * This function returns the parent datum of given XXX_datum_t
- * object or NULL, if it doesn't exist.
- *
- * If the given datum has a valid bounds, this function merely
- * returns the indicated object. Otherwise, it looks up the
- * parent based on the based hierarchy.
+static int bounds_insert_helper(sepol_handle_t *handle, avtab_t *avtab,
+				avtab_key_t *avtab_key, avtab_datum_t *datum)
+{
+	int rc = avtab_insert(avtab, avtab_key, datum);
+	if (rc) {
+		if (rc == SEPOL_ENOMEM)
+			ERR(handle, "Insufficient memory");
+		else
+			ERR(handle, "Unexpected error (%d)", rc);
+	}
+	return rc;
+}
+
+
+static int bounds_insert_rule(sepol_handle_t *handle, avtab_t *avtab,
+			      avtab_t *global, avtab_t *other,
+			      avtab_key_t *avtab_key, avtab_datum_t *datum)
+{
+	int rc = 0;
+	avtab_datum_t *dup = avtab_search(avtab, avtab_key);
+
+	if (!dup) {
+		rc = bounds_insert_helper(handle, avtab, avtab_key, datum);
+		if (rc) goto exit;
+	} else {
+		dup->data |= datum->data;
+	}
+
+	if (other) {
+		/* Search the other conditional avtab for the key and
+		 * add any common permissions to the global avtab
+		 */
+		uint32_t data = 0;
+		dup = avtab_search(other, avtab_key);
+		if (dup) {
+			data = dup->data & datum->data;
+			if (data) {
+				dup = avtab_search(global, avtab_key);
+				if (!dup) {
+					avtab_datum_t d;
+					d.data = data;
+					rc = bounds_insert_helper(handle, global,
+								  avtab_key, &d);
+					if (rc) goto exit;
+				} else {
+					dup->data |= data;
+				}
+			}
+		}
+	}
+
+exit:
+	return rc;
+}
+
+static int bounds_expand_rule(sepol_handle_t *handle, policydb_t *p,
+			      avtab_t *avtab, avtab_t *global, avtab_t *other,
+			      uint32_t parent, uint32_t src, uint32_t tgt,
+			      uint32_t class, uint32_t data)
+{
+	int rc = 0;
+	avtab_key_t avtab_key;
+	avtab_datum_t datum;
+	ebitmap_node_t *tnode;
+	unsigned int i;
+
+	avtab_key.specified = AVTAB_ALLOWED;
+	avtab_key.target_class = class;
+	datum.data = data;
+
+	if (ebitmap_get_bit(&p->attr_type_map[src - 1], parent - 1)) {
+		avtab_key.source_type = parent;
+		ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) {
+			if (!ebitmap_node_get_bit(tnode, i))
+				continue;
+			avtab_key.target_type = i + 1;
+			rc = bounds_insert_rule(handle, avtab, global, other,
+						&avtab_key, &datum);
+			if (rc) goto exit;
+		}
+	}
+
+	if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], parent - 1)) {
+		avtab_key.target_type = parent;
+		ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) {
+			if (!ebitmap_node_get_bit(tnode, i))
+				continue;
+			avtab_key.source_type = i + 1;
+			rc = bounds_insert_rule(handle, avtab, global, other,
+						&avtab_key, &datum);
+			if (rc) goto exit;
+		}
+	}
+
+exit:
+	return rc;
+}
+
+static int bounds_expand_cond_rules(sepol_handle_t *handle, policydb_t *p,
+				    cond_av_list_t *cur, avtab_t *avtab,
+				    avtab_t *global, avtab_t *other,
+				    uint32_t parent)
+{
+	int rc = 0;
+
+	for (; cur; cur = cur->next) {
+		avtab_ptr_t n = cur->node;
+		rc = bounds_expand_rule(handle, p, avtab, global, other, parent,
+					n->key.source_type, n->key.target_type,
+					n->key.target_class, n->datum.data);
+		if (rc) goto exit;
+	}
+
+exit:
+	return rc;
+}
+
+struct bounds_expand_args {
+	sepol_handle_t *handle;
+	policydb_t *p;
+	avtab_t *avtab;
+	uint32_t parent;
+};
+
+static int bounds_expand_rule_callback(avtab_key_t *k, avtab_datum_t *d,
+				       void *args)
+{
+	struct bounds_expand_args *a = (struct bounds_expand_args *)args;
+
+	if (!(k->specified & AVTAB_ALLOWED))
+		return 0;
+
+	return bounds_expand_rule(a->handle, a->p, a->avtab, NULL, NULL,
+				  a->parent, k->source_type, k->target_type,
+				  k->target_class, d->data);
+}
+
+struct bounds_cond_info {
+	avtab_t true_avtab;
+	avtab_t false_avtab;
+	cond_list_t *cond_list;
+	struct bounds_cond_info *next;
+};
+
+static void bounds_destroy_cond_info(struct bounds_cond_info *cur)
+{
+	struct bounds_cond_info *next;
+
+	for (; cur; cur = next) {
+		next = cur->next;
+		avtab_destroy(&cur->true_avtab);
+		avtab_destroy(&cur->false_avtab);
+		cur->next = NULL;
+		free(cur);
+	}
+}
+
+static int bounds_expand_parent_rules(sepol_handle_t *handle, policydb_t *p,
+				      avtab_t *global_avtab,
+				      struct bounds_cond_info **cond_info,
+				      uint32_t parent)
+{
+	int rc = 0;
+	struct bounds_expand_args args;
+	cond_list_t *cur;
+
+	avtab_init(global_avtab);
+	rc = avtab_alloc(global_avtab, BOUNDS_AVTAB_SIZE);
+	if (rc) goto oom;
+
+	args.handle = handle;
+	args.p = p;
+	args.avtab = global_avtab;
+	args.parent = parent;
+	rc = avtab_map(&p->te_avtab, bounds_expand_rule_callback, &args);
+	if (rc) goto exit;
+
+	*cond_info = NULL;
+	for (cur = p->cond_list; cur; cur = cur->next) {
+		struct bounds_cond_info *ci;
+		ci = malloc(sizeof(struct bounds_cond_info));
+		if (!ci) goto oom;
+		avtab_init(&ci->true_avtab);
+		avtab_init(&ci->false_avtab);
+		ci->cond_list = cur;
+		ci->next = *cond_info;
+		*cond_info = ci;
+		if (cur->true_list) {
+			rc = avtab_alloc(&ci->true_avtab, BOUNDS_AVTAB_SIZE);
+			if (rc) goto oom;
+			rc = bounds_expand_cond_rules(handle, p, cur->true_list,
+						      &ci->true_avtab, NULL,
+						      NULL, parent);
+			if (rc) goto exit;
+		}
+		if (cur->false_list) {
+			rc = avtab_alloc(&ci->false_avtab, BOUNDS_AVTAB_SIZE);
+			if (rc) goto oom;
+			rc = bounds_expand_cond_rules(handle, p, cur->false_list,
+						      &ci->false_avtab,
+						      global_avtab,
+						      &ci->true_avtab, parent);
+			if (rc) goto exit;
+		}
+	}
+
+	return 0;
+
+oom:
+	ERR(handle, "Insufficient memory");
+
+exit:
+	ERR(handle,"Failed to expand parent rules\n");
+	avtab_destroy(global_avtab);
+	bounds_destroy_cond_info(*cond_info);
+	*cond_info = NULL;
+	return rc;
+}
+
+static int bounds_not_covered(avtab_t *global_avtab, avtab_t *cur_avtab,
+			      avtab_key_t *avtab_key, uint32_t data)
+{
+	avtab_datum_t *datum = avtab_search(cur_avtab, avtab_key);
+	if (datum)
+		data &= ~datum->data;
+	if (global_avtab && data) {
+		datum = avtab_search(global_avtab, avtab_key);
+		if (datum)
+			data &= ~datum->data;
+	}
+
+	return data;
+}
+
+static int bounds_add_bad(sepol_handle_t *handle, uint32_t src, uint32_t tgt,
+			  uint32_t class, uint32_t data, avtab_ptr_t *bad)
+{
+	struct avtab_node *new = malloc(sizeof(struct avtab_node));
+	if (new == NULL) {
+		ERR(handle, "Insufficient memory");
+		return SEPOL_ENOMEM;
+	}
+	memset(new, 0, sizeof(struct avtab_node));
+	new->key.source_type = src;
+	new->key.target_type = tgt;
+	new->key.target_class = class;
+	new->datum.data = data;
+	new->next = *bad;
+	*bad = new;
+
+	return 0;
+}
+
+static int bounds_check_rule(sepol_handle_t *handle, policydb_t *p,
+			     avtab_t *global_avtab, avtab_t *cur_avtab,
+			     uint32_t child, uint32_t parent, uint32_t src,
+			     uint32_t tgt, uint32_t class, uint32_t data,
+			     avtab_ptr_t *bad, int *numbad)
+{
+	int rc = 0;
+	avtab_key_t avtab_key;
+	type_datum_t *td;
+	ebitmap_node_t *tnode;
+	unsigned int i;
+	uint32_t d;
+
+	avtab_key.specified = AVTAB_ALLOWED;
+	avtab_key.target_class = class;
+
+	if (ebitmap_get_bit(&p->attr_type_map[src - 1], child - 1)) {
+		avtab_key.source_type = parent;
+		ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) {
+			if (!ebitmap_node_get_bit(tnode, i))
+				continue;
+			avtab_key.target_type = i + 1;
+			d = bounds_not_covered(global_avtab, cur_avtab,
+					       &avtab_key, data);
+			if (!d) continue;
+			td = p->type_val_to_struct[i];
+			if (td && td->bounds) {
+				avtab_key.target_type = td->bounds;
+				d = bounds_not_covered(global_avtab, cur_avtab,
+						       &avtab_key, data);
+				if (!d) continue;
+			}
+			(*numbad)++;
+			rc = bounds_add_bad(handle, child, i+1, class, d, bad);
+			if (rc) goto exit;
+		}
+	}
+	if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], child - 1)) {
+		avtab_key.target_type = parent;
+		ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) {
+			if (!ebitmap_node_get_bit(tnode, i))
+				continue;
+			avtab_key.source_type = i + 1;
+			if (avtab_key.source_type == child) {
+				/* Checked above */
+				continue;
+			}
+			d = bounds_not_covered(global_avtab, cur_avtab,
+					       &avtab_key, data);
+			if (!d) continue;
+			td = p->type_val_to_struct[i];
+			if (td && td->bounds) {
+				avtab_key.source_type = td->bounds;
+				d = bounds_not_covered(global_avtab, cur_avtab,
+						       &avtab_key, data);
+				if (!d) continue;
+			}
+			(*numbad)++;
+			rc = bounds_add_bad(handle, i+1, child, class, d, bad);
+			if (rc) goto exit;
+		}
+	}
+
+exit:
+	return rc;
+}
+
+static int bounds_check_cond_rules(sepol_handle_t *handle, policydb_t *p,
+				   avtab_t *global_avtab, avtab_t *cond_avtab,
+				   cond_av_list_t *rules, uint32_t child,
+				   uint32_t parent, avtab_ptr_t *bad,
+				   int *numbad)
+{
+	int rc = 0;
+	cond_av_list_t *cur;
+
+	for (cur = rules; cur; cur = cur->next) {
+		avtab_ptr_t ap = cur->node;
+		avtab_key_t *key = &ap->key;
+		avtab_datum_t *datum = &ap->datum;
+		if (!(key->specified & AVTAB_ALLOWED))
+			continue;
+		rc = bounds_check_rule(handle, p, global_avtab, cond_avtab,
+				       child, parent, key->source_type,
+				       key->target_type, key->target_class,
+				       datum->data, bad, numbad);
+		if (rc) goto exit;
+	}
+
+exit:
+	return rc;
+}
+
+struct bounds_check_args {
+	sepol_handle_t *handle;
+	policydb_t *p;
+	avtab_t *cur_avtab;
+	uint32_t child;
+	uint32_t parent;
+	avtab_ptr_t bad;
+	int numbad;
+};
+
+static int bounds_check_rule_callback(avtab_key_t *k, avtab_datum_t *d,
+				      void *args)
+{
+	struct bounds_check_args *a = (struct bounds_check_args *)args;
+
+	if (!(k->specified & AVTAB_ALLOWED))
+		return 0;
+
+	return bounds_check_rule(a->handle, a->p, NULL, a->cur_avtab, a->child,
+				 a->parent, k->source_type, k->target_type,
+				 k->target_class, d->data, &a->bad, &a->numbad);
+}
+
+static int bounds_check_child_rules(sepol_handle_t *handle, policydb_t *p,
+				    avtab_t *global_avtab,
+				    struct bounds_cond_info *cond_info,
+				    uint32_t child, uint32_t parent,
+				    avtab_ptr_t *bad, int *numbad)
+{
+	int rc;
+	struct bounds_check_args args;
+	struct bounds_cond_info *cur;
+
+	args.handle = handle;
+	args.p = p;
+	args.cur_avtab = global_avtab;
+	args.child = child;
+	args.parent = parent;
+	args.bad = NULL;
+	args.numbad = 0;
+	rc = avtab_map(&p->te_avtab, bounds_check_rule_callback, &args);
+	if (rc) goto exit;
+
+	for (cur = cond_info; cur; cur = cur->next) {
+		cond_list_t *node = cur->cond_list;
+		rc = bounds_check_cond_rules(handle, p, global_avtab,
+					     &cur->true_avtab,
+					     node->true_list, child, parent,
+					     &args.bad, &args.numbad);
+		if (rc) goto exit;
+
+		rc = bounds_check_cond_rules(handle, p, global_avtab,
+					     &cur->false_avtab,
+					     node->false_list, child, parent,
+					     &args.bad, &args.numbad);
+		if (rc) goto exit;
+	}
+
+	*numbad += args.numbad;
+	*bad = args.bad;
+
+exit:
+	return rc;
+}
+
+int bounds_check_type(sepol_handle_t *handle, policydb_t *p, uint32_t child,
+		      uint32_t parent, avtab_ptr_t *bad, int *numbad)
+{
+	int rc = 0;
+	avtab_t global_avtab;
+	struct bounds_cond_info *cond_info = NULL;
+
+	rc = bounds_expand_parent_rules(handle, p, &global_avtab, &cond_info, parent);
+	if (rc) goto exit;
+
+	rc = bounds_check_child_rules(handle, p, &global_avtab, cond_info,
+				      child, parent, bad, numbad);
+
+	bounds_destroy_cond_info(cond_info);
+	avtab_destroy(&global_avtab);
+
+exit:
+	return rc;
+}
+
+struct bounds_args {
+	sepol_handle_t *handle;
+	policydb_t *p;
+	int numbad;
+};
+
+static void bounds_report(sepol_handle_t *handle, policydb_t *p, uint32_t child,
+			  uint32_t parent, avtab_ptr_t cur)
+{
+	ERR(handle, "Child type %s exceeds bounds of parent %s in the following rules:",
+	    p->p_type_val_to_name[child - 1],
+	    p->p_type_val_to_name[parent - 1]);
+	for (; cur; cur = cur->next) {
+		ERR(handle, "    %s %s : %s { %s }",
+		    p->p_type_val_to_name[cur->key.source_type - 1],
+		    p->p_type_val_to_name[cur->key.target_type - 1],
+		    p->p_class_val_to_name[cur->key.target_class - 1],
+		    sepol_av_to_string(p, cur->key.target_class,
+				       cur->datum.data));
+	}
+}
+
+void bounds_destroy_bad(avtab_ptr_t cur)
+{
+	avtab_ptr_t next;
+
+	for (; cur; cur = next) {
+		next = cur->next;
+		cur->next = NULL;
+		free(cur);
+	}
+}
+
+static int bounds_check_type_callback(hashtab_key_t k __attribute__ ((unused)),
+				      hashtab_datum_t d, void *args)
+{
+	int rc = 0;
+	struct bounds_args *a = (struct bounds_args *)args;
+	type_datum_t *t = (type_datum_t *)d;
+	avtab_ptr_t bad = NULL;
+
+	if (t->bounds) {
+		rc = bounds_check_type(a->handle, a->p, t->s.value, t->bounds,
+				       &bad, &a->numbad);
+		if (bad) {
+			bounds_report(a->handle, a->p, t->s.value, t->bounds,
+				      bad);
+			bounds_destroy_bad(bad);
+		}
+	}
+
+	return rc;
+}
+
+int bounds_check_types(sepol_handle_t *handle, policydb_t *p)
+{
+	int rc;
+	struct bounds_args args;
+
+	args.handle = handle;
+	args.p = p;
+	args.numbad = 0;
+
+	rc = hashtab_map(p->p_types.table, bounds_check_type_callback, &args);
+	if (rc) goto exit;
+
+	if (args.numbad > 0) {
+		ERR(handle, "%d errors found during type bounds check",
+		    args.numbad);
+		rc = SEPOL_ERR;
+	}
+
+exit:
+	return rc;
+}
+
+/* The role bounds is defined as: a child role cannot have a type that
+ * its parent doesn't have.
  */
-#define find_parent_template(prefix)				\
-int find_parent_##prefix(hierarchy_args_t *a,			\
-			 prefix##_datum_t *datum,		\
-			 prefix##_datum_t **parent)		\
+static int bounds_check_role_callback(hashtab_key_t k __attribute__ ((unused)),
+				      hashtab_datum_t d, void *args)
+{
+	struct bounds_args *a = (struct bounds_args *)args;
+	role_datum_t *r = (role_datum_t *) d;
+	role_datum_t *rp = NULL;
+
+	if (!r->bounds)
+		return 0;
+
+	rp = a->p->role_val_to_struct[r->bounds - 1];
+
+	if (rp && !ebitmap_contains(&rp->types.types, &r->types.types)) {
+		ERR(a->handle, "Role bounds violation, %s exceeds %s",
+		    (char *)k, a->p->p_role_val_to_name[rp->s.value - 1]);
+		a->numbad++;
+	}
+
+	return 0;
+}
+
+int bounds_check_roles(sepol_handle_t *handle, policydb_t *p)
+{
+	struct bounds_args args;
+
+	args.handle = handle;
+	args.p = p;
+	args.numbad = 0;
+
+	hashtab_map(p->p_roles.table, bounds_check_role_callback, &args);
+
+	if (args.numbad > 0) {
+		ERR(handle, "%d errors found during role bounds check",
+		    args.numbad);
+		return SEPOL_ERR;
+	}
+
+	return 0;
+}
+
+/* The user bounds is defined as: a child user cannot have a role that
+ * its parent doesn't have.
+ */
+static int bounds_check_user_callback(hashtab_key_t k __attribute__ ((unused)),
+				      hashtab_datum_t d, void *args)
+{
+	struct bounds_args *a = (struct bounds_args *)args;
+	user_datum_t *u = (user_datum_t *) d;
+	user_datum_t *up = NULL;
+
+	if (!u->bounds)
+		return 0;
+
+	up = a->p->user_val_to_struct[u->bounds - 1];
+
+	if (up && !ebitmap_contains(&up->roles.roles, &u->roles.roles)) {
+		ERR(a->handle, "User bounds violation, %s exceeds %s",
+		    (char *) k, a->p->p_user_val_to_name[up->s.value - 1]);
+		a->numbad++;
+	}
+
+	return 0;
+}
+
+int bounds_check_users(sepol_handle_t *handle, policydb_t *p)
+{
+	struct bounds_args args;
+
+	args.handle = handle;
+	args.p = p;
+	args.numbad = 0;
+
+	hashtab_map(p->p_users.table, bounds_check_user_callback, &args);
+
+	if (args.numbad > 0) {
+		ERR(handle, "%d errors found during user bounds check",
+		    args.numbad);
+		return SEPOL_ERR;
+	}
+
+	return 0;
+}
+
+#define add_hierarchy_callback_template(prefix)				\
+	int hierarchy_add_##prefix##_callback(hashtab_key_t k __attribute__ ((unused)), \
+					    hashtab_datum_t d, void *args) \
 {								\
-	char *parent_name, *datum_name, *tmp;			\
-								\
-	if (datum->bounds)						\
-		*parent = a->p->prefix##_val_to_struct[datum->bounds - 1]; \
-	else {								\
-		datum_name = a->p->p_##prefix##_val_to_name[datum->s.value - 1]; \
+	struct bounds_args *a = (struct bounds_args *)args;		\
+	sepol_handle_t *handle = a->handle;				\
+	policydb_t *p = a->p;						\
+	prefix##_datum_t *datum = (prefix##_datum_t *)d;		\
+	prefix##_datum_t *parent;					\
+	char *parent_name, *datum_name, *tmp;				\
+									\
+	if (!datum->bounds) {						\
+		datum_name = p->p_##prefix##_val_to_name[datum->s.value - 1]; \
 									\
 		tmp = strrchr(datum_name, '.');				\
 		/* no '.' means it has no parent */			\
-		if (!tmp) {						\
-			*parent = NULL;					\
-			return 0;					\
-		}							\
+		if (!tmp) return 0;					\
 									\
 		parent_name = strdup(datum_name);			\
-		if (!parent_name)					\
-			return -1;					\
+		if (!parent_name) {					\
+			ERR(handle, "Insufficient memory");		\
+			return SEPOL_ENOMEM;				\
+		}							\
 		parent_name[tmp - datum_name] = '\0';			\
 									\
-		*parent = hashtab_search(a->p->p_##prefix##s.table, parent_name); \
-		if (!*parent) {						\
+		parent = hashtab_search(p->p_##prefix##s.table, parent_name); \
+		if (!parent) {						\
 			/* Orphan type/role/user */			\
-			ERR(a->handle,					\
-			    "%s doesn't exist, %s is an orphan",	\
+			ERR(handle, "%s doesn't exist, %s is an orphan",\
 			    parent_name,				\
-			    a->p->p_##prefix##_val_to_name[datum->s.value - 1]); \
+			    p->p_##prefix##_val_to_name[datum->s.value - 1]); \
 			free(parent_name);				\
-			return -1;					\
+			a->numbad++;					\
+			return 0;					\
 		}							\
+		datum->bounds = parent->s.value;			\
 		free(parent_name);					\
 	}								\
 									\
 	return 0;							\
-}
+}								\
 
-static find_parent_template(type)
-static find_parent_template(role)
-static find_parent_template(user)
+static add_hierarchy_callback_template(type)
+static add_hierarchy_callback_template(role)
+static add_hierarchy_callback_template(user)
 
-static void compute_avtab_datum(hierarchy_args_t *args,
-				avtab_key_t *key,
-				avtab_datum_t *result)
+int hierarchy_add_bounds(sepol_handle_t *handle, policydb_t *p)
 {
-	avtab_datum_t *avdatp;
-	uint32_t av = 0;
+	int rc = 0;
+	struct bounds_args args;
 
-	avdatp = avtab_search(args->expa, key);
-	if (avdatp)
-		av = avdatp->data;
-	if (args->opt_cond_list) {
-		avdatp = cond_av_list_search(key, args->opt_cond_list);
-		if (avdatp)
-			av |= avdatp->data;
+	args.handle = handle;
+	args.p = p;
+	args.numbad = 0;
+
+	rc = hashtab_map(p->p_users.table, hierarchy_add_user_callback, &args);
+	if (rc) goto exit;
+
+	rc = hashtab_map(p->p_roles.table, hierarchy_add_role_callback, &args);
+	if (rc) goto exit;
+
+	rc = hashtab_map(p->p_types.table, hierarchy_add_type_callback, &args);
+	if (rc) goto exit;
+
+	if (args.numbad > 0) {
+		ERR(handle, "%d errors found while adding hierarchies",
+		    args.numbad);
+		rc = SEPOL_ERR;
 	}
 
-	result->data = av;
-}
-
-/* This function verifies that the type passed in either has a parent or is in the 
- * root of the namespace, 0 on success, 1 on orphan and -1 on error
- */
-static int check_type_hierarchy_callback(hashtab_key_t k, hashtab_datum_t d,
-					 void *args)
-{
-	hierarchy_args_t *a;
-	type_datum_t *t, *tp;
-
-	a = (hierarchy_args_t *) args;
-	t = (type_datum_t *) d;
-
-	if (t->flavor == TYPE_ATTRIB) {
-		/* It's an attribute, we don't care */
-		return 0;
-	}
-	if (find_parent_type(a, t, &tp) < 0)
-		return -1;
-
-	if (tp && tp->flavor == TYPE_ATTRIB) {
-		/* The parent is an attribute but the child isn't, not legal */
-		ERR(a->handle, "type %s is a child of an attribute %s",
-		    (char *) k, a->p->p_type_val_to_name[tp->s.value - 1]);
-		a->numerr++;
-		return -1;
-	}
-	return 0;
-}
-
-/* This function only verifies that the avtab node passed in does not violate any
- * hiearchy constraint via any relationship with other types in the avtab.
- * it should be called using avtab_map, returns 0 on success, 1 on violation and
- * -1 on error. opt_cond_list is an optional argument that tells this to check
- * a conditional list for the relationship as well as the unconditional avtab
- */
-static int check_avtab_hierarchy_callback(avtab_key_t * k, avtab_datum_t * d,
-					  void *args)
-{
-	avtab_key_t key;
-	hierarchy_args_t *a = (hierarchy_args_t *) args;
-	type_datum_t *s, *t1 = NULL, *t2 = NULL;
-	avtab_datum_t av;
-
-	if (!(k->specified & AVTAB_ALLOWED)) {
-		/* This is not an allow rule, no checking done */
-		return 0;
-	}
-
-	/* search for parent first */
-	s = a->p->type_val_to_struct[k->source_type - 1];
-	if (find_parent_type(a, s, &t1) < 0)
-		return -1;
-	if (t1) {
-		/*
-		 * search for access allowed between type 1's
-		 * parent and type 2.
-		 */
-		key.source_type = t1->s.value;
-		key.target_type = k->target_type;
-		key.target_class = k->target_class;
-		key.specified = AVTAB_ALLOWED;
-		compute_avtab_datum(a, &key, &av);
-
-		if ((av.data & d->data) == d->data)
-			return 0;
-	}
-
-	/* next we try type 1 and type 2's parent */
-	s = a->p->type_val_to_struct[k->target_type - 1];
-	if (find_parent_type(a, s, &t2) < 0)
-		return -1;
-	if (t2) {
-		/*
-		 * search for access allowed between type 1 and
-		 * type 2's parent.
-		 */
-		key.source_type = k->source_type;
-		key.target_type = t2->s.value;
-		key.target_class = k->target_class;
-		key.specified = AVTAB_ALLOWED;
-		compute_avtab_datum(a, &key, &av);
-
-		if ((av.data & d->data) == d->data)
-			return 0;
-	}
-
-	if (t1 && t2) {
-		/*
-                 * search for access allowed between type 1's parent
-                 * and type 2's parent.
-                 */
-		key.source_type = t1->s.value;
-		key.target_type = t2->s.value;
-		key.target_class = k->target_class;
-		key.specified = AVTAB_ALLOWED;
-		compute_avtab_datum(a, &key, &av);
-
-		if ((av.data & d->data) == d->data)
-			return 0;
-	}
-
-	/*
-	 * Neither one of these types have parents and 
-	 * therefore the hierarchical constraint does not apply
-	 */
-	if (!t1 && !t2)
-		return 0;
-
-	/*
-	 * At this point there is a violation of the hierarchal
-	 * constraint, send error condition back
-	 */
-	ERR(a->handle,
-	    "hierarchy violation between types %s and %s : %s { %s }",
-	    a->p->p_type_val_to_name[k->source_type - 1],
-	    a->p->p_type_val_to_name[k->target_type - 1],
-	    a->p->p_class_val_to_name[k->target_class - 1],
-	    sepol_av_to_string(a->p, k->target_class, d->data & ~av.data));
-	a->numerr++;
-	return 0;
-}
-
-/*
- * If same permissions are allowed for same combination of
- * source and target, we can evaluate them as unconditional
- * one.
- * See the following example. A_t type is bounds of B_t type,
- * so B_t can never have wider permissions then A_t.
- * A_t has conditional permission on X_t, however, a part of
- * them (getattr and read) are unconditionaly allowed to A_t.
- *
- * Example)
- * typebounds A_t B_t;
- *
- * allow B_t X_t : file { getattr };
- * if (foo_bool) {
- *     allow A_t X_t : file { getattr read };
- * } else {
- *     allow A_t X_t : file { getattr read write };
- * }
- *
- * We have to pull up them as unconditional ones in this case,
- * because it seems to us B_t is violated to bounds constraints
- * during unconditional policy checking.
- */
-static int pullup_unconditional_perms(cond_list_t * cond_list,
-				      hierarchy_args_t * args)
-{
-	cond_list_t *cur_node;
-	cond_av_list_t *cur_av, *expl_true = NULL, *expl_false = NULL;
-	avtab_t expa_true, expa_false;
-	avtab_datum_t *avdatp;
-	avtab_datum_t avdat;
-	avtab_ptr_t avnode;
-
-	for (cur_node = cond_list; cur_node; cur_node = cur_node->next) {
-		if (avtab_init(&expa_true))
-			goto oom0;
-		if (avtab_init(&expa_false))
-			goto oom1;
-		if (expand_cond_av_list(args->p, cur_node->true_list,
-					&expl_true, &expa_true))
-			goto oom2;
-		if (expand_cond_av_list(args->p, cur_node->false_list,
-					&expl_false, &expa_false))
-			goto oom3;
-		for (cur_av = expl_true; cur_av; cur_av = cur_av->next) {
-			avdatp = avtab_search(&expa_false,
-					      &cur_av->node->key);
-			if (!avdatp)
-				continue;
-
-			avdat.data = (cur_av->node->datum.data
-				      & avdatp->data);
-			if (!avdat.data)
-				continue;
-
-			avnode = avtab_search_node(args->expa,
-						   &cur_av->node->key);
-			if (avnode) {
-				avnode->datum.data |= avdat.data;
-			} else {
-				if (avtab_insert(args->expa,
-						 &cur_av->node->key,
-						 &avdat))
-					goto oom4;
-			}
-		}
-		cond_av_list_destroy(expl_false);
-		cond_av_list_destroy(expl_true);
-		avtab_destroy(&expa_false);
-		avtab_destroy(&expa_true);
-	}
-	return 0;
-
-oom4:
-	cond_av_list_destroy(expl_false);
-oom3:
-	cond_av_list_destroy(expl_true);
-oom2:
-	avtab_destroy(&expa_false);
-oom1:
-	avtab_destroy(&expa_true);
-oom0:
-	ERR(args->handle, "out of memory on conditional av list expansion");
-        return 1;
-}
-
-static int check_cond_avtab_hierarchy(cond_list_t * cond_list,
-				      hierarchy_args_t * args)
-{
-	int rc;
-	cond_list_t *cur_node;
-	cond_av_list_t *cur_av, *expl = NULL;
-	avtab_t expa;
-	hierarchy_args_t *a = (hierarchy_args_t *) args;
-	avtab_datum_t avdat, *uncond;
-
-	for (cur_node = cond_list; cur_node; cur_node = cur_node->next) {
-		/*
-		 * Check true condition
-		 */
-		if (avtab_init(&expa))
-			goto oom;
-		if (expand_cond_av_list(args->p, cur_node->true_list,
-					&expl, &expa)) {
-			avtab_destroy(&expa);
-			goto oom;
-		}
-		args->opt_cond_list = expl;
-		for (cur_av = expl; cur_av; cur_av = cur_av->next) {
-			avdat.data = cur_av->node->datum.data;
-			uncond = avtab_search(a->expa, &cur_av->node->key);
-			if (uncond)
-				avdat.data |= uncond->data;
-			rc = check_avtab_hierarchy_callback(&cur_av->node->key,
-							    &avdat, args);
-			if (rc)
-				args->numerr++;
-		}
-		cond_av_list_destroy(expl);
-		avtab_destroy(&expa);
-
-		/*
-		 * Check false condition
-		 */
-		if (avtab_init(&expa))
-			goto oom;
-		if (expand_cond_av_list(args->p, cur_node->false_list,
-					&expl, &expa)) {
-			avtab_destroy(&expa);
-			goto oom;
-		}
-		args->opt_cond_list = expl;
-		for (cur_av = expl; cur_av; cur_av = cur_av->next) {
-			avdat.data = cur_av->node->datum.data;
-			uncond = avtab_search(a->expa, &cur_av->node->key);
-			if (uncond)
-				avdat.data |= uncond->data;
-
-			rc = check_avtab_hierarchy_callback(&cur_av->node->key,
-							    &avdat, args);
-			if (rc)
-				a->numerr++;
-		}
-		cond_av_list_destroy(expl);
-		avtab_destroy(&expa);
-	}
-
-	return 0;
-
-      oom:
-	ERR(args->handle, "out of memory on conditional av list expansion");
-	return 1;
-}
-
-/* The role hierarchy is defined as: a child role cannot have more types than it's parent.
- * This function should be called with hashtab_map, it will return 0 on success, 1 on 
- * constraint violation and -1 on error
- */
-static int check_role_hierarchy_callback(hashtab_key_t k
-					 __attribute__ ((unused)),
-					 hashtab_datum_t d, void *args)
-{
-	hierarchy_args_t *a;
-	role_datum_t *r, *rp;
-
-	a = (hierarchy_args_t *) args;
-	r = (role_datum_t *) d;
-
-	if (find_parent_role(a, r, &rp) < 0)
-		return -1;
-
-	if (rp && !ebitmap_contains(&rp->types.types, &r->types.types)) {
-		/* hierarchical constraint violation, return error */
-		ERR(a->handle, "Role hierarchy violation, %s exceeds %s",
-		    (char *) k, a->p->p_role_val_to_name[rp->s.value - 1]);
-		a->numerr++;
-	}
-	return 0;
-}
-
-/* The user hierarchy is defined as: a child user cannot have a role that
- * its parent doesn't have.  This function should be called with hashtab_map,
- * it will return 0 on success, 1 on constraint violation and -1 on error.
- */
-static int check_user_hierarchy_callback(hashtab_key_t k
-					 __attribute__ ((unused)),
-					 hashtab_datum_t d, void *args)
-{
-	hierarchy_args_t *a;
-	user_datum_t *u, *up;
-
-	a = (hierarchy_args_t *) args;
-	u = (user_datum_t *) d;
-
-	if (find_parent_user(a, u, &up) < 0)
-		return -1;
-
-	if (up && !ebitmap_contains(&up->roles.roles, &u->roles.roles)) {
-		/* hierarchical constraint violation, return error */
-		ERR(a->handle, "User hierarchy violation, %s exceeds %s",
-		    (char *) k, a->p->p_user_val_to_name[up->s.value - 1]);
-		a->numerr++;
-	}
-	return 0;
+exit:
+	return rc;
 }
 
 int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p)
 {
-	hierarchy_args_t args;
-	avtab_t expa;
+	int rc = 0;
+	int violation = 0;
 
-	if (avtab_init(&expa))
-		goto oom;
-	if (expand_avtab(p, &p->te_avtab, &expa)) {
-		avtab_destroy(&expa);
-		goto oom;
+	rc = hierarchy_add_bounds(handle, p);
+	if (rc) goto exit;
+
+	rc = bounds_check_users(handle, p);
+	if (rc)
+		violation = 1;
+
+	rc = bounds_check_roles(handle, p);
+	if (rc)
+		violation = 1;
+
+	rc = bounds_check_types(handle, p);
+	if (rc) {
+		if (rc == SEPOL_ERR)
+			violation = 1;
+		else
+			goto exit;
 	}
 
-	args.p = p;
-	args.expa = &expa;
-	args.opt_cond_list = NULL;
-	args.handle = handle;
-	args.numerr = 0;
+	if (violation)
+		rc = SEPOL_ERR;
 
-	if (hashtab_map(p->p_types.table, check_type_hierarchy_callback, &args))
-		goto bad;
-
-	if (pullup_unconditional_perms(p->cond_list, &args))
-		return -1;
-
-	if (avtab_map(&expa, check_avtab_hierarchy_callback, &args))
-		goto bad;
-
-	if (check_cond_avtab_hierarchy(p->cond_list, &args))
-		goto bad;
-
-	if (hashtab_map(p->p_roles.table, check_role_hierarchy_callback, &args))
-		goto bad;
-
-	if (hashtab_map(p->p_users.table, check_user_hierarchy_callback, &args))
-		goto bad;
-
-	if (args.numerr) {
-		ERR(handle, "%d total errors found during hierarchy check",
-		    args.numerr);
-		goto bad;
-	}
-
-	avtab_destroy(&expa);
-	return 0;
-
-      bad:
-	avtab_destroy(&expa);
-	return -1;
-
-      oom:
-	ERR(handle, "Out of memory");
-	return -1;
+exit:
+	return rc;
 }
diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
index 2d8046c..18ec6b9 100644
--- a/libsepol/src/module_to_cil.c
+++ b/libsepol/src/module_to_cil.c
@@ -2859,7 +2859,7 @@
 	char *token = NULL;
 	char *ranged = NULL;
 
-	matched = sscanf(levelstr, "%m[^:]:%ms", &sens, &cats);
+	matched = tokenize(levelstr, ':', 2, &sens, &cats);
 	if (matched < 1 || matched > 2) {
 		log_err("Invalid level: %s", levelstr);
 		rc = -1;
@@ -2924,7 +2924,7 @@
 	char *type = NULL;
 	char *level = NULL;
 
-	matched = sscanf(contextstr, "%m[^:]:%m[^:]:%m[^:]:%ms", &user, &role, &type, &level);
+	matched = tokenize(contextstr, ':', 4, &user, &role, &type, &level);
 	if (matched < 3 || matched > 4) {
 		log_err("Invalid context: %s", contextstr);
 		rc = -1;
@@ -2965,6 +2965,7 @@
 	char *user = NULL;
 	char *seuser = NULL;
 	char *level = NULL;
+	char *tmp = NULL;
 	int matched;
 
 	if (seusers_len == 0) {
@@ -2972,11 +2973,18 @@
 	}
 
 	while ((rc = get_line(&cur, end, &line)) > 0) {
-		if (line[0] == '#') {
+		tmp = line;
+		while (isspace(*tmp)) {
+			tmp++;
+		}
+
+		if (tmp[0] == '#' || tmp[0] == '\0') {
+			free(line);
+			line = NULL;
 			continue;
 		}
 
-		matched = sscanf(line, "%m[^:]:%m[^:]:%ms", &user, &seuser, &level);
+		matched = tokenize(tmp, ':', 3, &user, &seuser, &level);
 
 		if (matched < 2 || matched > 3) {
 			log_err("Invalid seuser line: %s", line);
@@ -3045,28 +3053,51 @@
 	int matched;
 	char *user = NULL;
 	char *prefix = NULL;
+	int prefix_len = 0;
+	char *user_str = NULL;
+	char *prefix_str = NULL;
+	char *eol = NULL;
+	char *tmp = NULL;
 
 	if (userx_len == 0) {
 		return 0;
 	}
 
 	while ((rc = get_line(&cur, end, &line)) > 0) {
-		if (line[0] == '#') {
+		tmp = line;
+		while (isspace(*tmp)) {
+			tmp++;
+		}
+
+		if (tmp[0] == '#' || tmp[0] == '\0') {
+			free(line);
+			line = NULL;
 			continue;
 		}
 
-		matched = sscanf(line, "user %ms prefix %m[^;];", &user, &prefix);
-		if (matched != 2) {
+		matched = tokenize(tmp, ' ', 4, &user_str, &user, &prefix_str, &prefix);
+		if (matched != 4) {
 			rc = -1;
-			log_err("Invalid file context line: %s", line);
+			log_err("Invalid user extra line: %s", line);
 			goto exit;
 		}
 
+		prefix_len = strlen(prefix);
+		eol = prefix + prefix_len - 1;
+		if (*eol != ';' || strcmp(user_str, "user") || strcmp(prefix_str, "prefix")) {
+			rc = -1;
+			log_err("Invalid user extra line: %s", line);
+			goto exit;
+		}
+		*eol = '\0';
+
 		cil_println(0, "(userprefix %s %s)", user, prefix);
 		free(user);
 		free(prefix);
 		free(line);
-		user = prefix = line = NULL;
+		free(user_str);
+		free(prefix_str);
+		user = prefix = line = user_str = prefix_str = NULL;
 	}
 
 	if (rc == -1) {
@@ -3096,17 +3127,25 @@
 	char *mode = NULL;
 	char *context = NULL;
 	const char *cilmode;
+	char *tmp = NULL;
 
 	if (fc_len == 0) {
 		return 0;
 	}
 
 	while ((rc = get_line(&cur, end, &line)) > 0) {
-		if (line[0] == '#') {
+		tmp = line;
+		while (isspace(*tmp)) {
+			tmp++;
+		}
+
+		if (tmp[0] == '#' || tmp[0] == '\0') {
+			free(line);
+			line = NULL;
 			continue;
 		}
 
-		matched = sscanf(line, "%ms %ms %ms", &regex, &mode, &context);
+		matched = tokenize(tmp, ' ', 3, &regex, &mode, &context);
 		if (matched < 2 || matched > 3) {
 			rc = -1;
 			log_err("Invalid file context line: %s", line);
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index 8c3c7ac..665f7a9 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -180,7 +180,7 @@
 	},
 	{
 	 .type = POLICY_KERN,
-	 .version = POLICYDB_VERSION_IOCTL_OPERATIONS,
+	 .version = POLICYDB_VERSION_XPERMS_IOCTL,
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
 	 .target_platform = SEPOL_TARGET_SELINUX,
@@ -3936,6 +3936,10 @@
 			/* add the type itself as the degenerate case */
 			if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
 				goto bad;
+			if (p->type_val_to_struct[i] && p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
+				if (ebitmap_set_bit(&p->attr_type_map[i], i, 1))
+					goto bad;
+			}
 		}
 	}
 
diff --git a/libsepol/src/util.c b/libsepol/src/util.c
index a824e61..ff8f7f2 100644
--- a/libsepol/src/util.c
+++ b/libsepol/src/util.c
@@ -19,11 +19,15 @@
  */
 
 #include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <sepol/policydb/flask_types.h>
 #include <sepol/policydb/policydb.h>
+#include <sepol/policydb/util.h>
+#include <dso.h>
 
 struct val_to_name {
 	unsigned int val;
@@ -114,3 +118,169 @@
 
 	return avbuf;
 }
+
+#define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p))
+
+char *sepol_extended_perms_to_string(avtab_extended_perms_t *xperms)
+{
+	uint16_t value;
+	uint16_t low_bit;
+	uint16_t low_value;
+	unsigned int bit;
+	unsigned int in_range = 0;
+	static char xpermsbuf[2048];
+	xpermsbuf[0] = '\0';
+	char *p;
+	int len, xpermslen = 0;
+	p = xpermsbuf;
+
+	if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
+		&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
+		return NULL;
+
+	len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "ioctl { ");
+	p += len;
+	xpermslen += len;
+
+	for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
+		if (!xperm_test(bit, xperms->perms))
+			continue;
+
+		if (in_range && next_bit_in_range(bit, xperms->perms)) {
+			/* continue until high value found */
+			continue;
+		} else if (next_bit_in_range(bit, xperms->perms)) {
+			/* low value */
+			low_bit = bit;
+			in_range = 1;
+			continue;
+		}
+
+		if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
+			value = xperms->driver<<8 | bit;
+			low_value = xperms->driver<<8 | low_bit;
+			if (in_range) {
+				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, value);
+			} else {
+				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx ", value);
+			}
+		} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
+			value = bit << 8;
+			low_value = low_bit << 8;
+			if (in_range) {
+				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", low_value, (uint16_t) (value|0xff));
+			} else {
+				len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "0x%hx-0x%hx ", value, (uint16_t) (value|0xff));
+			}
+
+		}
+
+		if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
+			return NULL;
+
+		p += len;
+		xpermslen += len;
+		if (in_range)
+			in_range = 0;
+	}
+
+	len = snprintf(p, sizeof(xpermsbuf) - xpermslen, "}");
+	if (len < 0 || (size_t) len >= (sizeof(xpermsbuf) - xpermslen))
+		return NULL;
+
+	return xpermsbuf;
+}
+
+/*
+ * The tokenize and tokenize_str functions may be used to
+ * replace sscanf to read tokens from buffers.
+ */
+
+/* Read a token from a buffer */
+static inline int tokenize_str(char delim, char **str, char **ptr, size_t *len)
+{
+	char *tmp_buf = *ptr;
+	*str = NULL;
+
+	while (**ptr != '\0') {
+		if (isspace(delim) && isspace(**ptr)) {
+			(*ptr)++;
+			break;
+		} else if (!isspace(delim) && **ptr == delim) {
+			(*ptr)++;
+			break;
+		}
+
+		(*ptr)++;
+	}
+
+	*len = *ptr - tmp_buf;
+	/* If the end of the string has not been reached, this will ensure the
+	 * delimiter is not included when returning the token.
+	 */
+	if (**ptr != '\0') {
+		(*len)--;
+	}
+
+	*str = strndup(tmp_buf, *len);
+	if (!*str) {
+		return -1;
+	}
+
+	/* Squash spaces if the delimiter is a whitespace character */
+	while (**ptr != '\0' && isspace(delim) && isspace(**ptr)) {
+		(*ptr)++;
+	}
+
+	return 0;
+}
+
+/*
+ * line_buf - Buffer containing string to tokenize.
+ * delim - The delimiter used to tokenize line_buf. A whitespace delimiter will
+ *	    be tokenized using isspace().
+ * num_args - The number of parameter entries to process.
+ * ...      - A 'char **' for each parameter.
+ * returns  - The number of items processed.
+ *
+ * This function calls tokenize_str() to do the actual string processing. The
+ * caller is responsible for calling free() on each additional argument. The
+ * function will not tokenize more than num_args and the last argument will
+ * contain the remaining content of line_buf. If the delimiter is any whitespace
+ * character, then all whitespace will be squashed.
+ */
+int hidden tokenize(char *line_buf, char delim, int num_args, ...)
+{
+	char **arg, *buf_p;
+	int rc, items;
+	size_t arg_len = 0;
+	va_list ap;
+
+	buf_p = line_buf;
+
+	/* Process the arguments */
+	va_start(ap, num_args);
+
+	for (items = 0; items < num_args && *buf_p != '\0'; items++) {
+		arg = va_arg(ap, char **);
+
+		/* Save the remainder of the string in arg */
+		if (items == num_args - 1) {
+			*arg = strdup(buf_p);
+			if (*arg == NULL) {
+				goto exit;
+			}
+
+			continue;
+		}
+
+		rc = tokenize_str(delim, arg, &buf_p, &arg_len);
+		if (rc < 0) {
+			goto exit;
+		}
+	}
+
+exit:
+	va_end(ap);
+	return items;
+}
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 6e78eb3..d87ea61 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -221,28 +221,32 @@
 	items = put_entry(buf16, sizeof(uint16_t), 4, fp);
 	if (items != 4)
 		return POLICYDB_ERROR;
-	if ((p->policyvers < POLICYDB_VERSION_IOCTL_OPERATIONS) &&
-			(cur->key.specified & AVTAB_OP)) {
-		ERR(fp->handle, "policy version %u does not support ioctl operation"
-				" rules and one was specified", p->policyvers);
+	if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) &&
+			(cur->key.specified & AVTAB_XPERMS)) {
+		ERR(fp->handle, "policy version %u does not support ioctl extended"
+				"permissions rules and one was specified", p->policyvers);
 		return POLICYDB_ERROR;
 	}
 
 	if (p->target_platform != SEPOL_TARGET_SELINUX &&
-			(cur->key.specified & AVTAB_OP)) {
+			(cur->key.specified & AVTAB_XPERMS)) {
 		ERR(fp->handle, "Target platform %s does not support ioctl "
-				"operation rules and one was specified",
+				"extended permissions rules and one was specified",
 				policydb_target_strings[p->target_platform]);
 		return POLICYDB_ERROR;
 	}
 
-	if (cur->key.specified & AVTAB_OP) {
-		buf8 = cur->datum.ops->type;
+	if (cur->key.specified & AVTAB_XPERMS) {
+		buf8 = cur->datum.xperms->specified;
 		items = put_entry(&buf8, sizeof(uint8_t),1,fp);
 		if (items != 1)
 			return POLICYDB_ERROR;
-		for (i = 0; i < ARRAY_SIZE(cur->datum.ops->perms); i++)
-			buf32[i] = cpu_to_le32(cur->datum.ops->perms[i]);
+		buf8 = cur->datum.xperms->driver;
+		items = put_entry(&buf8, sizeof(uint8_t),1,fp);
+		if (items != 1)
+			return POLICYDB_ERROR;
+		for (i = 0; i < ARRAY_SIZE(cur->datum.xperms->perms); i++)
+			buf32[i] = cpu_to_le32(cur->datum.xperms->perms[i]);
 		items = put_entry(buf32, sizeof(uint32_t),8,fp);
 		if (items != 8)
 			return POLICYDB_ERROR;
@@ -1546,9 +1550,9 @@
 	uint32_t buf[32], len;
 	class_perm_node_t *cur;
 
-	if (avrule->specified & AVRULE_OP) {
-		ERR(fp->handle, "module policy does not support ioctl operation"
-				" rules and one was specified");
+	if (avrule->specified & AVRULE_XPERMS) {
+		ERR(fp->handle, "module policy does not support extended"
+				" permissions rules and one was specified");
 		return POLICYDB_ERROR;
 	}
 
diff --git a/policycoreutils/ChangeLog b/policycoreutils/ChangeLog
index cc2bc71..f78e5c0 100644
--- a/policycoreutils/ChangeLog
+++ b/policycoreutils/ChangeLog
@@ -1,3 +1,11 @@
+	* audit2allow/why: ignore setlocale errors, from Petr Lautrbach.
+	* semodule: Add --extract/-E, --cil/-c, and --hll/-H to extract modules, from Yuli Khodorkovskiy.
+	* audit2allow: Comment constraint rules in output, from Miroslav Grepl via Petr Lautrbach.
+	* Fix PEP8 issues, from Jason Zaman.
+	* semanage: fix moduleRecords deleteall method, from Stephen Smalley.
+	* Improve compatibility with Python 3, from Michal Srb.
+	* semanage: Set self.sename to sename after calling semanage_seuser_set_sename(), from Laurent Bigonville.
+	* semanage: Fix typo in semanage args for minimium policy store, from Petr Lautrbach.
 	* sepolicy: Only invoke RPM on RPM-enabled Linux distributions, from Sven Vermeulen.
 	* mcstransd: don't reinvent getpeercon, from Stephen Smalley.
 	* setfiles/restorecon: fix -r/-R option, from Petr Lautrbach.
diff --git a/policycoreutils/audit2allow/audit2allow b/policycoreutils/audit2allow/audit2allow
index c9713a2..e23e418 100755
--- a/policycoreutils/audit2allow/audit2allow
+++ b/policycoreutils/audit2allow/audit2allow
@@ -19,7 +19,8 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
 
-import sys, os
+import sys
+import os
 
 import sepolgen.audit as audit
 import sepolgen.policygen as policygen
@@ -31,7 +32,11 @@
 from sepolgen.sepolgeni18n import _
 import selinux.audit2why as audit2why
 import locale
-locale.setlocale(locale.LC_ALL, '')
+try:
+    locale.setlocale(locale.LC_ALL, '')
+except:
+    pass
+
 
 class AuditToPolicy:
     VERSION = "%prog .1"
@@ -65,8 +70,8 @@
                           help="generate a module package - conflicts with -o and -m")
         parser.add_option("-o", "--output", dest="output",
                           help="append output to <filename>, conflicts with -M")
-        parser.add_option("-D", "--dontaudit", action="store_true", 
-                          dest="dontaudit", default=False, 
+        parser.add_option("-D", "--dontaudit", action="store_true",
+                          dest="dontaudit", default=False,
                           help="generate policy with dontaudit rules")
         parser.add_option("-R", "--reference", action="store_true", dest="refpolicy",
                           default=True, help="generate refpolicy style output")
@@ -83,7 +88,7 @@
         parser.add_option("--interface-info", dest="interface_info", help="file name of interface information")
         parser.add_option("--debug", dest="debug", action="store_true", default=False,
                           help="leave generated modules for -M")
-        parser.add_option("-w", "--why", dest="audit2why",  action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"),
+        parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0]) == "audit2why"),
                           help="Translates SELinux audit messages into a description of why the access was denied")
 
         options, args = parser.parse_args()
@@ -135,13 +140,13 @@
         elif self.__options.audit:
             try:
                 messages = audit.get_audit_msgs()
-            except OSError, e:
+            except OSError as e:
                 sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
                 sys.exit(1)
         elif self.__options.boot:
             try:
                 messages = audit.get_audit_boot_msgs()
-            except OSError, e:
+            except OSError as e:
                 sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
                 sys.exit(1)
         else:
@@ -152,7 +157,7 @@
         if filename is not None:
             try:
                 f = open(filename)
-            except IOError, e:
+            except IOError as e:
                 sys.stderr.write('could not open file %s - "%s"\n' % (filename, str(e)))
                 sys.exit(1)
 
@@ -214,7 +219,7 @@
 
         try:
             fd = open(filename, "w")
-        except IOError, e:
+        except IOError as e:
             sys.stderr.write("could not write output file: %s\n" % str(e))
             sys.exit(1)
 
@@ -225,71 +230,71 @@
 
         try:
             mc.create_module_package(filename, self.__options.refpolicy)
-        except RuntimeError, e:
-            print e
+        except RuntimeError as e:
+            print(e)
             sys.exit(1)
 
         sys.stdout.write(_("******************** IMPORTANT ***********************\n"))
-        sys.stdout.write((_("To make this policy package active, execute:" +\
-                                "\n\nsemodule -i %s\n\n") % packagename))
+        sys.stdout.write((_("To make this policy package active, execute:" +
+                            "\n\nsemodule -i %s\n\n") % packagename))
 
     def __output_audit2why(self):
-            import selinux
-            import seobject
-            for i in self.__parser.avc_msgs:
-                rc = i.type
-                data = i.data
-                if rc >= 0:
-                    print "%s\n\tWas caused by:" % i.message
-                if rc == audit2why.ALLOW:
-                    print "\t\tUnknown - would be allowed by active policy\n",
-                    print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
-                    print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
-                    continue
-                if rc == audit2why.DONTAUDIT:
-                    print "\t\tUnknown - should be dontaudit'd by active policy\n",
-                    print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
-                    print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
-                    continue
-                if rc == audit2why.BOOLEAN:
-                    if len(data) > 1:
-                        print "\tOne of the following booleans was set incorrectly."
-                        for b in data:
-                            print "\tDescription:\n\t%s\n"  % seobject.boolean_desc(b[0])
-                            print "\tAllow access by executing:\n\t# setsebool -P %s %d"  % (b[0], b[1])
-                    else:
-                        print "\tThe boolean %s was set incorrectly. " % (data[0][0])
-                        print "\tDescription:\n\t%s\n"  % seobject.boolean_desc(data[0][0])
-                        print "\tAllow access by executing:\n\t# setsebool -P %s %d"  % (data[0][0], data[0][1])
-                    continue
+        import selinux
+        import seobject
+        for i in self.__parser.avc_msgs:
+            rc = i.type
+            data = i.data
+            if rc >= 0:
+                print("%s\n\tWas caused by:" % i.message)
+            if rc == audit2why.ALLOW:
+                print("\t\tUnknown - would be allowed by active policy")
+                print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+                print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+                continue
+            if rc == audit2why.DONTAUDIT:
+                print("\t\tUnknown - should be dontaudit'd by active policy")
+                print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+                print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+                continue
+            if rc == audit2why.BOOLEAN:
+                if len(data) > 1:
+                    print("\tOne of the following booleans was set incorrectly.")
+                    for b in data:
+                        print("\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0]))
+                        print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1]))
+                else:
+                    print("\tThe boolean %s was set incorrectly. " % (data[0][0]))
+                    print("\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0]))
+                    print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1]))
+                continue
 
-                if rc == audit2why.TERULE:
-                    print "\t\tMissing type enforcement (TE) allow rule.\n"
-                    print "\t\tYou can use audit2allow to generate a loadable module to allow this access.\n"
-                    continue
+            if rc == audit2why.TERULE:
+                print("\t\tMissing type enforcement (TE) allow rule.\n")
+                print("\t\tYou can use audit2allow to generate a loadable module to allow this access.\n")
+                continue
 
-                if rc == audit2why.CONSTRAINT:
-                    print #!!!! This avc is a constraint violation.  You would need to modify the attributes of either the source or target types to allow this access.\n"
-                    print "#Constraint rule:"
-                    print "\n\t" + data[0]
-                    for reason in data[1:]:
-                        print "#\tPossible cause is the source %s and target %s are different.\n" % reason
+            if rc == audit2why.CONSTRAINT:
+                print()  # !!!! This avc is a constraint violation.  You would need to modify the attributes of either the source or target types to allow this access.\n"
+                print("#Constraint rule:")
+                print("\n#\t" + data[0])
+                for reason in data[1:]:
+                    print("#\tPossible cause is the source %s and target %s are different.\n" % reason)
 
-                if rc == audit2why.RBAC:
-                    print "\t\tMissing role allow rule.\n"
-                    print "\t\tAdd an allow rule for the role pair.\n"
-                    continue
+            if rc == audit2why.RBAC:
+                print("\t\tMissing role allow rule.\n")
+                print("\t\tAdd an allow rule for the role pair.\n")
+                continue
 
-            audit2why.finish()
-            return
+        audit2why.finish()
+        return
 
     def __output(self):
-        
+
         if self.__options.audit2why:
             try:
                 return self.__output_audit2why()
-            except RuntimeError, e:
-                print e
+            except RuntimeError as e:
+                print(e)
                 sys.exit(1)
 
         g = policygen.PolicyGenerator()
@@ -348,11 +353,11 @@
             self.__output()
         except KeyboardInterrupt:
             sys.exit(0)
-        except ValueError, e:
-            print e
+        except ValueError as e:
+            print(e)
             sys.exit(1)
-        except IOError, e:
-            print e
+        except IOError as e:
+            print(e)
             sys.exit(1)
 
 if __name__ == "__main__":
diff --git a/policycoreutils/audit2allow/audit2why b/policycoreutils/audit2allow/audit2why
index 323eddd..b1489ed 100755
--- a/policycoreutils/audit2allow/audit2why
+++ b/policycoreutils/audit2allow/audit2why
@@ -19,7 +19,8 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
 
-import sys, os
+import sys
+import os
 
 import sepolgen.audit as audit
 import sepolgen.policygen as policygen
@@ -31,7 +32,11 @@
 from sepolgen.sepolgeni18n import _
 import selinux.audit2why as audit2why
 import locale
-locale.setlocale(locale.LC_ALL, '')
+try:
+    locale.setlocale(locale.LC_ALL, '')
+except:
+    pass
+
 
 class AuditToPolicy:
     VERSION = "%prog .1"
@@ -83,7 +88,7 @@
         parser.add_option("--interface-info", dest="interface_info", help="file name of interface information")
         parser.add_option("--debug", dest="debug", action="store_true", default=False,
                           help="leave generated modules for -M")
-        parser.add_option("-w", "--why", dest="audit2why",  action="store_true", default=(os.path.basename(sys.argv[0])=="audit2why"),
+        parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0]) == "audit2why"),
                           help="Translates SELinux audit messages into a description of why the access was denied")
 
         options, args = parser.parse_args()
@@ -135,13 +140,13 @@
         elif self.__options.audit:
             try:
                 messages = audit.get_audit_msgs()
-            except OSError, e:
+            except OSError as e:
                 sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
                 sys.exit(1)
         elif self.__options.boot:
             try:
                 messages = audit.get_audit_boot_msgs()
-            except OSError, e:
+            except OSError as e:
                 sys.stderr.write('could not run ausearch - "%s"\n' % str(e))
                 sys.exit(1)
         else:
@@ -152,7 +157,7 @@
         if filename is not None:
             try:
                 f = open(filename)
-            except IOError, e:
+            except IOError as e:
                 sys.stderr.write('could not open file %s - "%s"\n' % (filename, str(e)))
                 sys.exit(1)
 
@@ -214,7 +219,7 @@
 
         try:
             fd = open(filename, "w")
-        except IOError, e:
+        except IOError as e:
             sys.stderr.write("could not write output file: %s\n" % str(e))
             sys.exit(1)
 
@@ -225,70 +230,70 @@
 
         try:
             mc.create_module_package(filename, self.__options.refpolicy)
-        except RuntimeError, e:
-            print e
+        except RuntimeError as e:
+            print(e)
             sys.exit(1)
 
         sys.stdout.write(_("******************** IMPORTANT ***********************\n"))
-        sys.stdout.write((_("To make this policy package active, execute:" +\
-                                "\n\nsemodule -i %s\n\n") % packagename))
+        sys.stdout.write((_("To make this policy package active, execute:" +
+                            "\n\nsemodule -i %s\n\n") % packagename))
 
     def __output_audit2why(self):
-            import selinux
-            import seobject
-            for i in self.__parser.avc_msgs:
-                rc = i.type
-                data = i.data
-                if rc >= 0:
-                    print "%s\n\tWas caused by:" % i.message
-                if rc == audit2why.ALLOW:
-                    print "\t\tUnknown - would be allowed by active policy\n",
-                    print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
-                    print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
-                    continue
-                if rc == audit2why.DONTAUDIT:
-                    print "\t\tUnknown - should be dontaudit'd by active policy\n",
-                    print "\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n"
-                    print "\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n"
-                    continue
-                if rc == audit2why.BOOLEAN:
-                    if len(data) > 1:
-                        print "\tOne of the following booleans was set incorrectly."
-                        for b in data:
-                            print "\tDescription:\n\t%s\n"  % seobject.boolean_desc(b[0])
-                            print "\tAllow access by executing:\n\t# setsebool -P %s %d"  % (b[0], b[1])
-                    else:
-                        print "\tThe boolean %s was set incorrectly. " % (data[0][0])
-                        print "\tDescription:\n\t%s\n"  % seobject.boolean_desc(data[0][0])
-                        print "\tAllow access by executing:\n\t# setsebool -P %s %d"  % (data[0][0], data[0][1])
-                    continue
+        import selinux
+        import seobject
+        for i in self.__parser.avc_msgs:
+            rc = i.type
+            data = i.data
+            if rc >= 0:
+                print("%s\n\tWas caused by:" % i.message)
+            if rc == audit2why.ALLOW:
+                print("\t\tUnknown - would be allowed by active policy")
+                print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+                print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+                continue
+            if rc == audit2why.DONTAUDIT:
+                print("\t\tUnknown - should be dontaudit'd by active policy")
+                print("\t\tPossible mismatch between this policy and the one under which the audit message was generated.\n")
+                print("\t\tPossible mismatch between current in-memory boolean settings vs. permanent ones.\n")
+                continue
+            if rc == audit2why.BOOLEAN:
+                if len(data) > 1:
+                    print("\tOne of the following booleans was set incorrectly.")
+                    for b in data:
+                        print("\tDescription:\n\t%s\n" % seobject.boolean_desc(b[0]))
+                        print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1]))
+                else:
+                    print("\tThe boolean %s was set incorrectly. " % (data[0][0]))
+                    print("\tDescription:\n\t%s\n" % seobject.boolean_desc(data[0][0]))
+                    print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1]))
+                continue
 
-                if rc == audit2why.TERULE:
-                    print "\t\tMissing type enforcement (TE) allow rule.\n"
-                    print "\t\tYou can use audit2allow to generate a loadable module to allow this access.\n"
-                    continue
+            if rc == audit2why.TERULE:
+                print("\t\tMissing type enforcement (TE) allow rule.\n")
+                print("\t\tYou can use audit2allow to generate a loadable module to allow this access.\n")
+                continue
 
-                if rc == audit2why.CONSTRAINT:
-                    print #!!!! This avc is a constraint violation.  You would need to modify the attributes of either the source or target types to allow this access.\n"
-                    print "#Constraint rule: \n\t" + data[0]
-                    for reason in data[1:]:
-                        print "#\tPossible cause is the source %s and target %s are different.\n\b" % reason
+            if rc == audit2why.CONSTRAINT:
+                print()  # !!!! This avc is a constraint violation.  You would need to modify the attributes of either the source or target types to allow this access.\n"
+                print("#Constraint rule: \n\t" + data[0])
+                for reason in data[1:]:
+                    print("#\tPossible cause is the source %s and target %s are different.\n\b" % reason)
 
-                if rc == audit2why.RBAC:
-                    print "\t\tMissing role allow rule.\n"
-                    print "\t\tAdd an allow rule for the role pair.\n"
-                    continue
+            if rc == audit2why.RBAC:
+                print("\t\tMissing role allow rule.\n")
+                print("\t\tAdd an allow rule for the role pair.\n")
+                continue
 
-            audit2why.finish()
-            return
+        audit2why.finish()
+        return
 
     def __output(self):
 
         if self.__options.audit2why:
             try:
                 return self.__output_audit2why()
-            except RuntimeError, e:
-                print e
+            except RuntimeError as e:
+                print(e)
                 sys.exit(1)
 
         g = policygen.PolicyGenerator()
@@ -347,11 +352,11 @@
             self.__output()
         except KeyboardInterrupt:
             sys.exit(0)
-        except ValueError, e:
-            print e
+        except ValueError as e:
+            print(e)
             sys.exit(1)
-        except IOError, e:
-            print e
+        except IOError as e:
+            print(e)
             sys.exit(1)
 
 if __name__ == "__main__":
diff --git a/policycoreutils/audit2allow/sepolgen-ifgen b/policycoreutils/audit2allow/sepolgen-ifgen
index 83c7ecf..acf9638 100644
--- a/policycoreutils/audit2allow/sepolgen-ifgen
+++ b/policycoreutils/audit2allow/sepolgen-ifgen
@@ -2,7 +2,7 @@
 #
 # Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
 #
-# Copyright (C) 2006 Red Hat 
+# Copyright (C) 2006 Red Hat
 # see file 'COPYING' for use and warranty information
 #
 # This program is free software; you can redistribute it and/or
@@ -41,6 +41,7 @@
 VERSION = "%prog .1"
 ATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper"
 
+
 def parse_options():
     from optparse import OptionParser
 
@@ -54,13 +55,14 @@
     parser.add_option("-v", "--verbose", action="store_true", default=False,
                       help="print debuging output")
     parser.add_option("-d", "--debug", action="store_true", default=False,
-                     help="extra debugging output")
+                      help="extra debugging output")
     parser.add_option("--no_attrs", action="store_true", default=False,
                       help="do not retrieve attribute access from kernel policy")
     options, args = parser.parse_args()
-    
+
     return options
 
+
 def get_policy():
     p = selinux.selinux_current_policy_path()
     if p and os.path.exists(p):
@@ -74,6 +76,7 @@
         return p
     return None
 
+
 def get_attrs(policy_path):
     try:
         if not policy_path:
@@ -82,14 +85,14 @@
             sys.stderr.write("No installed policy to check\n")
             return None
         outfile = tempfile.NamedTemporaryFile()
-    except IOError, e:
+    except IOError as e:
         sys.stderr.write("could not open attribute output file\n")
         return None
     except OSError:
         # SELinux Disabled Machine
         return None
 
-    fd = open("/dev/null","w")
+    fd = open("/dev/null", "w")
     ret = subprocess.Popen([ATTR_HELPER, policy_path, outfile.name], stdout=fd).wait()
     fd.close()
     if ret != 0:
@@ -100,18 +103,19 @@
     try:
         attrs.from_file(outfile)
     except:
-        print "error parsing attribute info"
+        print("error parsing attribute info")
         return None
 
     return attrs
 
+
 def main():
     options = parse_options()
 
     # Open the output first to generate errors before parsing
     try:
         f = open(options.output, "w")
-    except IOError, e:
+    except IOError as e:
         sys.stderr.write("could not open output file [%s]\n" % options.output)
         return 1
 
@@ -130,9 +134,9 @@
     # Parse the headers
     try:
         headers = refparser.parse_headers(options.headers, output=log, debug=options.debug)
-    except ValueError, e:
-        print "error parsing headers"
-        print str(e)
+    except ValueError as e:
+        print("error parsing headers")
+        print(str(e))
         return 1
 
     if_set = interfaces.InterfaceSet(output=log)
@@ -144,6 +148,6 @@
         return 0
     else:
         return 1
-    
+
 if __name__ == "__main__":
     sys.exit(main())
diff --git a/policycoreutils/audit2allow/test_audit2allow.py b/policycoreutils/audit2allow/test_audit2allow.py
index 794673e..765c9ea 100644
--- a/policycoreutils/audit2allow/test_audit2allow.py
+++ b/policycoreutils/audit2allow/test_audit2allow.py
@@ -1,26 +1,31 @@
-import unittest, os, shutil
+import unittest
+import os
+import shutil
 from tempfile import mkdtemp
 from subprocess import Popen, PIPE
 
+
 class Audit2allowTests(unittest.TestCase):
+
     def assertDenied(self, err):
-        self.assert_('Permission denied' in err,
-                     '"Permission denied" not found in %r' % err)
+        self.assertTrue('Permission denied' in err,
+                        '"Permission denied" not found in %r' % err)
+
     def assertNotFound(self, err):
-        self.assert_('not found' in err,
-                     '"not found" not found in %r' % err)
+        self.assertTrue('not found' in err,
+                        '"not found" not found in %r' % err)
 
     def assertFailure(self, status):
-        self.assert_(status != 0,
-                     '"Succeeded when it should have failed')
+        self.assertTrue(status != 0,
+                        '"Succeeded when it should have failed')
 
     def assertSuccess(self, cmd, status, err):
-        self.assert_(status == 0,
-                     '"%s should have succeeded for this test %r' %  (cmd, err))
+        self.assertTrue(status == 0,
+                        '"%s should have succeeded for this test %r' % (cmd, err))
 
     def test_sepolgen_ifgen(self):
         "Verify sepolgen-ifgen works"
-        p = Popen(['sudo', 'sepolgen-ifgen'], stdout = PIPE)
+        p = Popen(['sudo', 'sepolgen-ifgen'], stdout=PIPE)
         out, err = p.communicate()
         if err:
             print(out, err)
@@ -28,7 +33,7 @@
 
     def test_audit2allow(self):
         "Verify audit2allow works"
-        p = Popen(['audit2allow',"-i","test.log"], stdout = PIPE)
+        p = Popen(['audit2allow', "-i", "test.log"], stdout=PIPE)
         out, err = p.communicate()
         if err:
             print(out, err)
@@ -36,7 +41,7 @@
 
     def test_audit2why(self):
         "Verify audit2why works"
-        p = Popen(['audit2why',"-i","test.log"], stdout = PIPE)
+        p = Popen(['audit2why', "-i", "test.log"], stdout=PIPE)
         out, err = p.communicate()
         if err:
             print(out, err)
diff --git a/policycoreutils/gui/booleansPage.py b/policycoreutils/gui/booleansPage.py
index eee954d..507a79d 100644
--- a/policycoreutils/gui/booleansPage.py
+++ b/policycoreutils/gui/booleansPage.py
@@ -28,18 +28,18 @@
 import seobject
 import semanagePage
 
-INSTALLPATH='/usr/share/system-config-selinux'
+INSTALLPATH = '/usr/share/system-config-selinux'
 sys.path.append(INSTALLPATH)
 
 import commands
-ENFORCING=0
-PERMISSIVE=1
-DISABLED=2
+ENFORCING = 0
+PERMISSIVE = 1
+DISABLED = 2
 
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -48,41 +48,47 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
 from glob import fnmatch
 
-class Modifier:
-    def __init__(self,name, on, save):
-        self.on=on
-        self.name=name
-        self.save=save
 
-    def set(self,value):
-        self.on=value
-        self.save=True
+class Modifier:
+
+    def __init__(self, name, on, save):
+        self.on = on
+        self.name = name
+        self.save = save
+
+    def set(self, value):
+        self.on = value
+        self.save = True
 
     def isOn(self):
         return self.on
 
+
 class Boolean(Modifier):
-    def __init__(self,name, val, save=False):
-        Modifier.__init__(self,name, val, save)
+
+    def __init__(self, name, val, save=False):
+        Modifier.__init__(self, name, val, save)
 
 ACTIVE = 0
 MODULE = 1
 DESC = 2
 BOOLEAN = 3
 
+
 class booleansPage:
+
     def __init__(self, xml, doDebug=None):
         self.xml = xml
         self.window = self.xml.get_widget("mainWindow").get_root_window()
         self.local = False
-        self.types=[]
+        self.types = []
         self.selinuxsupport = True
         self.typechanged = False
         self.doDebug = doDebug
@@ -112,7 +118,7 @@
 
         checkbox = gtk.CellRendererToggle()
         checkbox.connect("toggled", self.boolean_toggled)
-        col = gtk.TreeViewColumn('Active', checkbox, active = ACTIVE)
+        col = gtk.TreeViewColumn('Active', checkbox, active=ACTIVE)
         col.set_clickable(True)
         col.set_sort_column_id(ACTIVE)
         self.booleansView.append_column(col)
@@ -123,7 +129,7 @@
         self.booleansView.append_column(col)
 
         col = gtk.TreeViewColumn("Description", gtk.CellRendererText(), text=DESC)
-	col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
         col.set_fixed_width(400)
         col.set_sort_column_id(DESC)
         col.set_resizable(True)
@@ -134,7 +140,7 @@
         col.set_resizable(True)
         self.booleansView.set_search_equal_func(self.__search)
         self.booleansView.append_column(col)
-        self.filter=""
+        self.filter = ""
         self.load(self.filter)
 
     def error(self, message):
@@ -182,10 +188,10 @@
             self.error(e.args[0])
 
     def filter_changed(self, *arg):
-        filter =  arg[0].get_text()
+        filter = arg[0].get_text()
         if filter != self.filter:
             self.load(filter)
-            self.filter=filter
+            self.filter = filter
 
     def use_menus(self):
         return False
@@ -193,17 +199,16 @@
     def get_description(self):
         return _("Boolean")
 
-    def match(self,key, filter=""):
+    def match(self, key, filter=""):
         try:
-            f=filter.lower()
-            cat=self.booleans.get_category(key).lower()
-            val=self.booleans.get_desc(key).lower()
-            k=key.lower()
+            f = filter.lower()
+            cat = self.booleans.get_category(key).lower()
+            val = self.booleans.get_desc(key).lower()
+            k = key.lower()
             return val.find(f) >= 0 or k.find(f) >= 0 or cat.find(f) >= 0
         except:
             return False
 
-
     def load(self, filter=None):
         self.store.clear()
         self.booleans = seobject.booleanRecords()
@@ -211,7 +216,7 @@
         for name in booleansList:
             rec = booleansList[name]
             if self.match(name, filter):
-                iter=self.store.append()
+                iter = self.store.append()
                 self.store.set_value(iter, ACTIVE, rec[2] == 1)
                 self.store.set_value(iter, MODULE, self.booleans.get_category(name))
                 self.store.set_value(iter, DESC, self.booleans.get_desc(name))
@@ -221,10 +226,10 @@
         iter = self.store.get_iter(row)
         val = self.store.get_value(iter, ACTIVE)
         key = self.store.get_value(iter, BOOLEAN)
-        self.store.set_value(iter, ACTIVE , not val)
+        self.store.set_value(iter, ACTIVE, not val)
         self.wait()
-        setsebool="/usr/sbin/setsebool -P %s %d" % (key, not val)
-        rc,out = commands.getstatusoutput(setsebool)
+        setsebool = "/usr/sbin/setsebool -P %s %d" % (key, not val)
+        rc, out = commands.getstatusoutput(setsebool)
         if rc != 0:
             self.error(out)
         self.load(self.filter)
@@ -232,7 +237,7 @@
 
     def on_revert_clicked(self, button):
         self.wait()
-        setsebool="semanage boolean --deleteall"
+        setsebool = "semanage boolean --deleteall"
         commands.getstatusoutput(setsebool)
         self.load(self.filter)
         self.ready()
diff --git a/policycoreutils/gui/domainsPage.py b/policycoreutils/gui/domainsPage.py
index 6af1e9a..56c66fe 100644
--- a/policycoreutils/gui/domainsPage.py
+++ b/policycoreutils/gui/domainsPage.py
@@ -25,13 +25,13 @@
 import sys
 import seobject
 import selinux
-from semanagePage import *;
+from semanagePage import *
 from sepolicy import get_all_entrypoint_domains
 
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
@@ -39,12 +39,14 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 class domainsPage(semanagePage):
+
     def __init__(self, xml):
         semanagePage.__init__(self, xml, "domains", _("Process Domain"))
         self.domain_filter = xml.get_widget("domainsFilterEntry")
@@ -54,12 +56,12 @@
         self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
         self.view.set_model(self.store)
         self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Domain Name"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Domain Name"), gtk.CellRendererText(), text=0)
         col.set_sort_column_id(0)
         col.set_resizable(True)
         self.view.append_column(col)
         self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Mode"), gtk.CellRendererText(), text = 1)
+        col = gtk.TreeViewColumn(_("Mode"), gtk.CellRendererText(), text=1)
         col.set_sort_column_id(1)
         col.set_resizable(True)
         self.view.append_column(col)
@@ -68,12 +70,12 @@
         self.permissive_button = xml.get_widget("permissiveButton")
         self.enforcing_button = xml.get_widget("enforcingButton")
 
-        self.domains=get_all_entrypoint_domains()
+        self.domains = get_all_entrypoint_domains()
         self.load()
 
     def get_modules(self):
-        modules=[]
-        fd=os.popen("semodule -l")
+        modules = []
+        fd = os.popen("semodule -l")
         mods = fd.readlines()
         fd.close()
         for l in mods:
@@ -81,10 +83,10 @@
         return modules
 
     def load(self, filter=""):
-        self.filter=filter
+        self.filter = filter
         self.store.clear()
         try:
-            modules=self.get_modules()
+            modules = self.get_modules()
             for domain in self.domains:
                 if not self.match(domain, filter):
                     continue
@@ -97,7 +99,7 @@
                     self.store.set_value(iter, 1, "")
         except:
             pass
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
     def itemSelected(self, selection):
         store, iter = selection.get_selected()
diff --git a/policycoreutils/gui/fcontextPage.py b/policycoreutils/gui/fcontextPage.py
index 131f1c2..c8d6ba8 100644
--- a/policycoreutils/gui/fcontextPage.py
+++ b/policycoreutils/gui/fcontextPage.py
@@ -22,16 +22,18 @@
 import gobject
 import seobject
 import commands
-from semanagePage import *;
+from semanagePage import *
 
 SPEC_COL = 0
 TYPE_COL = 1
 FTYPE_COL = 2
 
+
 class context:
+
     def __init__(self, scontext):
         self.scontext = scontext
-        con=scontext.split(":")
+        con = scontext.split(":")
         self.type = con[0]
         if len(con) > 1:
             self.mls = con[1]
@@ -44,7 +46,7 @@
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -53,13 +55,14 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
 
 class fcontextPage(semanagePage):
+
     def __init__(self, xml):
         semanagePage.__init__(self, xml, "fcontext", _("File Labeling"))
         self.fcontextFilter = xml.get_widget("fcontextFilterEntry")
@@ -72,16 +75,16 @@
         self.view.set_search_equal_func(self.search)
 
         col = gtk.TreeViewColumn(_("File\nSpecification"), gtk.CellRendererText(), text=SPEC_COL)
-	col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-	col.set_fixed_width(250)
+        col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        col.set_fixed_width(250)
 
         col.set_sort_column_id(SPEC_COL)
         col.set_resizable(True)
         self.view.append_column(col)
         col = gtk.TreeViewColumn(_("Selinux\nFile Type"), gtk.CellRendererText(), text=TYPE_COL)
 
-	col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-	col.set_fixed_width(250)
+        col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        col.set_fixed_width(250)
         col.set_sort_column_id(TYPE_COL)
         col.set_resizable(True)
         self.view.append_column(col)
@@ -94,10 +97,10 @@
         self.load()
         self.fcontextEntry = xml.get_widget("fcontextEntry")
         self.fcontextFileTypeCombo = xml.get_widget("fcontextFileTypeCombo")
-        liststore=self.fcontextFileTypeCombo.get_model()
+        liststore = self.fcontextFileTypeCombo.get_model()
         for k in seobject.file_types:
-            if len(k) > 0 and  k[0] != '-':
-                iter=liststore.append()
+            if len(k) > 0 and k[0] != '-':
+                iter = liststore.append()
                 liststore.set_value(iter, 0, k)
         iter = liststore.get_iter_first()
         self.fcontextFileTypeCombo.set_active_iter(iter)
@@ -106,13 +109,13 @@
 
     def match(self, fcon_dict, k, filter):
         try:
-            f=filter.lower()
+            f = filter.lower()
             for con in k:
-                k=con.lower()
+                k = con.lower()
                 if k.find(f) >= 0:
                     return True
             for con in fcon_dict[k]:
-                k=con.lower()
+                k = con.lower()
                 if k.find(f) >= 0:
                     return True
         except:
@@ -120,27 +123,27 @@
         return False
 
     def load(self, filter=""):
-        self.filter=filter
-        self.fcontext=seobject.fcontextRecords()
+        self.filter = filter
+        self.fcontext = seobject.fcontextRecords()
         self.store.clear()
-        fcon_dict=self.fcontext.get_all(self.local)
+        fcon_dict = self.fcontext.get_all(self.local)
         keys = fcon_dict.keys()
         keys.sort()
         for k in keys:
             if not self.match(fcon_dict, k, filter):
                 continue
-            iter=self.store.append()
+            iter = self.store.append()
             self.store.set_value(iter, SPEC_COL, k[0])
             self.store.set_value(iter, FTYPE_COL, k[1])
             if fcon_dict[k]:
-                rec="%s:%s" % (fcon_dict[k][2], seobject.translate(fcon_dict[k][3],False))
+                rec = "%s:%s" % (fcon_dict[k][2], seobject.translate(fcon_dict[k][3], False))
             else:
-                rec="<<None>>"
+                rec = "<<None>>"
             self.store.set_value(iter, TYPE_COL, rec)
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
     def filter_changed(self, *arg):
-        filter =  arg[0].get_text()
+        filter = arg[0].get_text()
         if filter != self.filter:
             self.load(filter)
 
@@ -149,13 +152,13 @@
         self.fcontextEntry.set_text(store.get_value(iter, SPEC_COL))
         self.fcontextEntry.set_sensitive(False)
         scontext = store.get_value(iter, TYPE_COL)
-        scon=context(scontext)
+        scon = context(scontext)
         self.fcontextTypeEntry.set_text(scon.type)
         self.fcontextMLSEntry.set_text(scon.mls)
-        type=store.get_value(iter, FTYPE_COL)
-        liststore=self.fcontextFileTypeCombo.get_model()
+        type = store.get_value(iter, FTYPE_COL)
+        liststore = self.fcontextFileTypeCombo.get_model()
         iter = liststore.get_iter_first()
-        while iter != None and liststore.get_value(iter,0) != type:
+        while iter != None and liststore.get_value(iter, 0) != type:
             iter = liststore.iter_next(iter)
         if iter != None:
             self.fcontextFileTypeCombo.set_active_iter(iter)
@@ -171,8 +174,8 @@
     def delete(self):
         store, iter = self.view.get_selection().get_selected()
         try:
-            fspec=store.get_value(iter, SPEC_COL)
-            ftype=store.get_value(iter, FTYPE_COL)
+            fspec = store.get_value(iter, SPEC_COL)
+            ftype = store.get_value(iter, FTYPE_COL)
             self.wait()
             (rc, out) = commands.getstatusoutput("semanage fcontext -d -f '%s' '%s'" % (ftype, fspec))
             self.ready()
@@ -180,16 +183,16 @@
             if rc != 0:
                 return self.error(out)
             store.remove(iter)
-            self.view.get_selection().select_path ((0,))
+            self.view.get_selection().select_path((0,))
         except ValueError, e:
             self.error(e.args[0])
 
     def add(self):
-        ftype=["", "--", "-d", "-c", "-b", "-s", "-l", "-p" ]
-        fspec=self.fcontextEntry.get_text().strip()
-        type=self.fcontextTypeEntry.get_text().strip()
-        mls=self.fcontextMLSEntry.get_text().strip()
-        list_model=self.fcontextFileTypeCombo.get_model()
+        ftype = ["", "--", "-d", "-c", "-b", "-s", "-l", "-p"]
+        fspec = self.fcontextEntry.get_text().strip()
+        type = self.fcontextTypeEntry.get_text().strip()
+        mls = self.fcontextMLSEntry.get_text().strip()
+        list_model = self.fcontextFileTypeCombo.get_model()
         active = self.fcontextFileTypeCombo.get_active()
         self.wait()
         (rc, out) = commands.getstatusoutput("semanage fcontext -a -t %s -r %s -f '%s' '%s'" % (type, mls, ftype[active], fspec))
@@ -198,18 +201,18 @@
             self.error(out)
             return False
 
-        iter=self.store.append()
+        iter = self.store.append()
         self.store.set_value(iter, SPEC_COL, fspec)
         self.store.set_value(iter, FTYPE_COL, ftype)
         self.store.set_value(iter, TYPE_COL, "%s:%s" % (type, mls))
 
     def modify(self):
-        fspec=self.fcontextEntry.get_text().strip()
-        type=self.fcontextTypeEntry.get_text().strip()
-        mls=self.fcontextMLSEntry.get_text().strip()
-        list_model=self.fcontextFileTypeCombo.get_model()
+        fspec = self.fcontextEntry.get_text().strip()
+        type = self.fcontextTypeEntry.get_text().strip()
+        mls = self.fcontextMLSEntry.get_text().strip()
+        list_model = self.fcontextFileTypeCombo.get_model()
         iter = self.fcontextFileTypeCombo.get_active_iter()
-        ftype=list_model.get_value(iter,0)
+        ftype = list_model.get_value(iter, 0)
         self.wait()
         (rc, out) = commands.getstatusoutput("semanage fcontext -m -t %s -r %s -f '%s' '%s'" % (type, mls, ftype, fspec))
         self.ready()
diff --git a/policycoreutils/gui/html_util.py b/policycoreutils/gui/html_util.py
index 68eed76..5a596bc 100644
--- a/policycoreutils/gui/html_util.py
+++ b/policycoreutils/gui/html_util.py
@@ -34,7 +34,9 @@
 
 #------------------------------------------------------------------------------
 
+
 class TextWriter(Formatter.DumbWriter):
+
     def __init__(self, file=None, maxcol=80, indent_width=4):
         Formatter.DumbWriter.__init__(self, file, maxcol)
         self.indent_level = 0
@@ -58,7 +60,8 @@
             self.send_literal_data(' ' * offset + data)
 
     def send_flowing_data(self, data):
-        if not data: return
+        if not data:
+            return
         atbreak = self.atbreak or data[0] in string.whitespace
         col = self.col
         maxcol = self.maxcol
@@ -81,6 +84,7 @@
         self.col = col
         self.atbreak = data[-1] in string.whitespace
 
+
 class HTMLParserAnchor(htmllib.HTMLParser):
 
     def __init__(self, formatter, verbose=0):
@@ -96,9 +100,11 @@
 
 #------------------------------------------------------------------------------
 
+
 def escape_html(s):
-    if s is None: return None
-    s = s.replace("&", "&amp;") # Must be done first!
+    if s is None:
+        return None
+    s = s.replace("&", "&amp;")  # Must be done first!
     s = s.replace("<", "&lt;")
     s = s.replace(">", "&gt;")
     s = s.replace("'", "&apos;")
@@ -107,16 +113,18 @@
 
 
 def unescape_html(s):
-    if s is None: return None
+    if s is None:
+        return None
     if '&' not in s:
         return s
     s = s.replace("&lt;", "<")
     s = s.replace("&gt;", ">")
     s = s.replace("&apos;", "'")
     s = s.replace("&quot;", '"')
-    s = s.replace("&amp;", "&") # Must be last
+    s = s.replace("&amp;", "&")  # Must be last
     return s
 
+
 def html_to_text(html, maxcol=80):
     try:
         buffer = StringIO.StringIO()
@@ -131,6 +139,7 @@
         log_program.error('cannot convert html to text: %s' % e)
         return None
 
+
 def html_document(*body_components):
     '''Wrap the body components in a HTML document structure with a valid header.
     Accepts a variable number of arguments of of which canb be:
diff --git a/policycoreutils/gui/loginsPage.py b/policycoreutils/gui/loginsPage.py
index ec29fd9..982e252 100644
--- a/policycoreutils/gui/loginsPage.py
+++ b/policycoreutils/gui/loginsPage.py
@@ -24,12 +24,12 @@
 import sys
 import commands
 import seobject
-from semanagePage import *;
+from semanagePage import *
 
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
@@ -37,26 +37,28 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 class loginsPage(semanagePage):
+
     def __init__(self, xml):
         self.firstTime = False
         semanagePage.__init__(self, xml, "logins", _("User Mapping"))
         self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
         self.view.set_model(self.store)
         self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Login\nName"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Login\nName"), gtk.CellRendererText(), text=0)
         col.set_sort_column_id(0)
         col.set_resizable(True)
         self.view.append_column(col)
-        col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text = 1)
+        col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=1)
         col.set_resizable(True)
         self.view.append_column(col)
-        col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text = 2)
+        col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=2)
         col.set_resizable(True)
         self.view.append_column(col)
         self.load()
@@ -64,8 +66,8 @@
         self.loginsSelinuxUserCombo = xml.get_widget("loginsSelinuxUserCombo")
         self.loginsMLSEntry = xml.get_widget("loginsMLSEntry")
 
-    def load(self, filter = ""):
-        self.filter=filter
+    def load(self, filter=""):
+        self.filter = filter
         self.login = seobject.loginRecords()
         dict = self.login.get_all(0)
         keys = dict.keys()
@@ -79,7 +81,7 @@
             self.store.set_value(iter, 0, k)
             self.store.set_value(iter, 1, dict[k][0])
             self.store.set_value(iter, 2, range)
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
     def __dialogSetup(self):
         if self.firstTime == True:
@@ -99,7 +101,7 @@
                 self.loginsSelinuxUserCombo.append_text(k)
 
         iter = liststore.get_iter_first()
-        while liststore.get_value(iter,0) != "user_u":
+        while liststore.get_value(iter, 0) != "user_u":
             iter = liststore.iter_next(iter)
         self.loginsSelinuxUserCombo.set_active_iter(iter)
 
@@ -113,12 +115,11 @@
         seuser = store.get_value(iter, 1)
         liststore = self.loginsSelinuxUserCombo.get_model()
         iter = liststore.get_iter_first()
-        while iter != None and liststore.get_value(iter,0) != seuser:
+        while iter != None and liststore.get_value(iter, 0) != seuser:
             iter = liststore.iter_next(iter)
         if iter != None:
             self.loginsSelinuxUserCombo.set_active_iter(iter)
 
-
     def dialogClear(self):
         self.__dialogSetup()
         self.loginsNameEntry.set_text("")
@@ -128,7 +129,7 @@
     def delete(self):
         store, iter = self.view.get_selection().get_selected()
         try:
-            login=store.get_value(iter, 0)
+            login = store.get_value(iter, 0)
             if login == "root" or login == "__default__":
                 raise ValueError(_("Login '%s' is required") % login)
 
@@ -139,18 +140,18 @@
                 self.error(out)
                 return False
             store.remove(iter)
-            self.view.get_selection().select_path ((0,))
+            self.view.get_selection().select_path((0,))
         except ValueError, e:
             self.error(e.args[0])
 
     def add(self):
-        target=self.loginsNameEntry.get_text().strip()
-        serange=self.loginsMLSEntry.get_text().strip()
+        target = self.loginsNameEntry.get_text().strip()
+        serange = self.loginsMLSEntry.get_text().strip()
         if serange == "":
-            serange="s0"
-        list_model=self.loginsSelinuxUserCombo.get_model()
+            serange = "s0"
+        list_model = self.loginsSelinuxUserCombo.get_model()
         iter = self.loginsSelinuxUserCombo.get_active_iter()
-        seuser = list_model.get_value(iter,0)
+        seuser = list_model.get_value(iter, 0)
         self.wait()
         (rc, out) = commands.getstatusoutput("semanage login -a -s %s -r %s %s" % (seuser, serange, target))
         self.ready()
@@ -164,13 +165,13 @@
         self.store.set_value(iter, 2, seobject.translate(serange))
 
     def modify(self):
-        target=self.loginsNameEntry.get_text().strip()
-        serange=self.loginsMLSEntry.get_text().strip()
+        target = self.loginsNameEntry.get_text().strip()
+        serange = self.loginsMLSEntry.get_text().strip()
         if serange == "":
             serange = "s0"
         list_model = self.loginsSelinuxUserCombo.get_model()
         iter = self.loginsSelinuxUserCombo.get_active_iter()
-        seuser=list_model.get_value(iter,0)
+        seuser = list_model.get_value(iter, 0)
         self.wait()
         (rc, out) = commands.getstatusoutput("semanage login -m -s %s -r %s %s" % (seuser, serange, target))
         self.ready()
diff --git a/policycoreutils/gui/mappingsPage.py b/policycoreutils/gui/mappingsPage.py
index fd0ea75..1429bf7 100644
--- a/policycoreutils/gui/mappingsPage.py
+++ b/policycoreutils/gui/mappingsPage.py
@@ -27,7 +27,7 @@
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
@@ -35,12 +35,14 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 class loginsPage:
+
     def __init__(self, xml):
         self.xml = xml
         self.view = xml.get_widget("mappingsView")
diff --git a/policycoreutils/gui/modulesPage.py b/policycoreutils/gui/modulesPage.py
index 9ff0766..3b83e45 100644
--- a/policycoreutils/gui/modulesPage.py
+++ b/policycoreutils/gui/modulesPage.py
@@ -25,13 +25,13 @@
 import sys
 import seobject
 import selinux
-from semanagePage import *;
+from semanagePage import *
 from subprocess import Popen, PIPE
 
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
@@ -39,12 +39,14 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 class modulesPage(semanagePage):
+
     def __init__(self, xml):
         semanagePage.__init__(self, xml, "modules", _("Policy Module"))
         self.module_filter = xml.get_widget("modulesFilterEntry")
@@ -55,12 +57,12 @@
         self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
         self.view.set_model(self.store)
         self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Module Name"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Module Name"), gtk.CellRendererText(), text=0)
         col.set_sort_column_id(0)
         col.set_resizable(True)
         self.view.append_column(col)
         self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), text = 1)
+        col = gtk.TreeViewColumn(_("Version"), gtk.CellRendererText(), text=1)
         self.enable_audit_button = xml.get_widget("enableAuditButton")
         self.enable_audit_button.connect("clicked", self.enable_audit)
         self.new_button = xml.get_widget("newModuleButton")
@@ -68,15 +70,15 @@
         col.set_sort_column_id(1)
         col.set_resizable(True)
         self.view.append_column(col)
-        self.store.set_sort_func(1,self.sort_int, "")
+        self.store.set_sort_func(1, self.sort_int, "")
         status, self.policy_type = selinux.selinux_getpolicytype()
 
         self.load()
 
     def sort_int(self, treemodel, iter1, iter2, user_data):
         try:
-            p1 = int(treemodel.get_value(iter1,1))
-            p2 = int(treemodel.get_value(iter1,1))
+            p1 = int(treemodel.get_value(iter1, 1))
+            p2 = int(treemodel.get_value(iter1, 1))
             if p1 > p2:
                 return 1
             if p1 == p2:
@@ -86,7 +88,7 @@
             return 0
 
     def load(self, filter=""):
-        self.filter=filter
+        self.filter = filter
         self.store.clear()
         try:
             fd = Popen("semodule -l", shell=True, stdout=PIPE).stdout
@@ -101,8 +103,7 @@
                 self.store.set_value(iter, 1, ver.strip())
         except:
             pass
-        self.view.get_selection().select_path ((0,))
-
+        self.view.get_selection().select_path((0,))
 
     def new_module(self, args):
         try:
@@ -121,7 +122,7 @@
                 self.error(output)
             else:
                 store.remove(iter)
-                self.view.get_selection().select_path ((0,))
+                self.view.get_selection().select_path((0,))
 
         except ValueError, e:
             self.error(e.args[0])
@@ -131,10 +132,10 @@
         try:
             self.wait()
             if self.audit_enabled:
-                status, output =commands.getstatusoutput("semodule -DB")
+                status, output = commands.getstatusoutput("semodule -DB")
                 button.set_label(_("Disable Audit"))
             else:
-                status, output =commands.getstatusoutput("semodule -B")
+                status, output = commands.getstatusoutput("semodule -B")
                 button.set_label(_("Enable Audit"))
             self.ready()
 
@@ -147,7 +148,7 @@
     def disable_audit(self, button):
         try:
             self.wait()
-            status, output =commands.getstatusoutput("semodule -B")
+            status, output = commands.getstatusoutput("semodule -B")
             self.ready()
             if status != 0:
                 self.error(output)
@@ -180,7 +181,7 @@
     def add(self, file):
         try:
             self.wait()
-            status, output =commands.getstatusoutput("semodule -i %s" % file)
+            status, output = commands.getstatusoutput("semodule -i %s" % file)
             self.ready()
             if status != 0:
                 self.error(output)
diff --git a/policycoreutils/gui/polgengui.py b/policycoreutils/gui/polgengui.py
index 0f0e564..0a153c6 100644
--- a/policycoreutils/gui/polgengui.py
+++ b/policycoreutils/gui/polgengui.py
@@ -30,7 +30,7 @@
 import sys
 try:
     from sepolicy import generate
-except ValueError,e:
+except ValueError, e:
     sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
     sys.exit(1)
 
@@ -39,10 +39,11 @@
 
 import re
 
+
 def get_all_modules():
     try:
         all_modules = []
-        rc, output=commands.getstatusoutput("semodule -l 2>/dev/null")
+        rc, output = commands.getstatusoutput("semodule -l 2>/dev/null")
         if rc == 0:
             l = output.split("\n")
             for i in l:
@@ -56,7 +57,7 @@
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -65,7 +66,7 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
@@ -78,6 +79,8 @@
 sys.path.append('.')
 
 # From John Hunter http://www.daa.com.au/pipermail/pygtk/2003-February/004454.html
+
+
 def foreach(model, path, iter, selected):
     selected.append(model.get_value(iter, 0))
 
@@ -85,13 +88,14 @@
 ## Pull in the Glade file
 ##
 if os.access("polgen.glade", os.F_OK):
-    xml = gtk.glade.XML ("polgen.glade", domain=PROGNAME)
+    xml = gtk.glade.XML("polgen.glade", domain=PROGNAME)
 else:
-    xml = gtk.glade.XML ("/usr/share/system-config-selinux/polgen.glade", domain=PROGNAME)
+    xml = gtk.glade.XML("/usr/share/system-config-selinux/polgen.glade", domain=PROGNAME)
 
 FILE = 1
 DIR = 2
 
+
 class childWindow:
     START_PAGE = 0
     SELECT_TYPE_PAGE = 0
@@ -111,82 +115,82 @@
 
     def __init__(self):
         self.xml = xml
-        self.notebook = xml.get_widget ("notebook")
+        self.notebook = xml.get_widget("notebook")
         self.label_dict = {}
         self.tooltip_dict = {}
-        label = xml.get_widget ("select_label")
+        label = xml.get_widget("select_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_user_roles_label")
+        label = xml.get_widget("select_user_roles_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_dir_label")
+        label = xml.get_widget("select_dir_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_domain_admin_label")
+        label = xml.get_widget("select_domain_admin_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_in_label")
+        label = xml.get_widget("select_in_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_out_label")
+        label = xml.get_widget("select_out_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_common_label")
+        label = xml.get_widget("select_common_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_manages_label")
+        label = xml.get_widget("select_manages_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("select_booleans_label")
+        label = xml.get_widget("select_booleans_label")
         self.label_dict[label] = label.get_text()
 
-        label = xml.get_widget ("existing_user_treeview")
+        label = xml.get_widget("existing_user_treeview")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("transition_treeview")
+        label = xml.get_widget("transition_treeview")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_tcp_all_checkbutton")
+        label = xml.get_widget("in_tcp_all_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_tcp_reserved_checkbutton")
+        label = xml.get_widget("in_tcp_reserved_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_tcp_unreserved_checkbutton")
+        label = xml.get_widget("in_tcp_unreserved_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_tcp_entry")
+        label = xml.get_widget("in_tcp_entry")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_udp_all_checkbutton")
+        label = xml.get_widget("in_udp_all_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_udp_reserved_checkbutton")
+        label = xml.get_widget("in_udp_reserved_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_udp_unreserved_checkbutton")
+        label = xml.get_widget("in_udp_unreserved_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("in_udp_entry")
+        label = xml.get_widget("in_udp_entry")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("out_tcp_entry")
+        label = xml.get_widget("out_tcp_entry")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("out_udp_entry")
+        label = xml.get_widget("out_udp_entry")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("out_tcp_all_checkbutton")
+        label = xml.get_widget("out_tcp_all_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("out_udp_all_checkbutton")
+        label = xml.get_widget("out_udp_all_checkbutton")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("boolean_treeview")
+        label = xml.get_widget("boolean_treeview")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
-        label = xml.get_widget ("write_treeview")
+        label = xml.get_widget("write_treeview")
         self.tooltip_dict[label] = label.get_tooltip_text()
 
         try:
@@ -201,7 +205,7 @@
             self.all_users = []
             self.error(str(e))
 
-        self.name=""
+        self.name = ""
         xml.signal_connect("on_delete_clicked", self.delete)
         xml.signal_connect("on_delete_boolean_clicked", self.delete_boolean)
         xml.signal_connect("on_exec_select_clicked", self.exec_select)
@@ -210,68 +214,67 @@
         xml.signal_connect("on_add_boolean_clicked", self.add_boolean)
         xml.signal_connect("on_add_dir_clicked", self.add_dir)
         xml.signal_connect("on_about_clicked", self.on_about_clicked)
-        xml.get_widget ("cancel_button").connect("clicked",self.quit)
-        self.forward_button = xml.get_widget ("forward_button")
-        self.forward_button.connect("clicked",self.forward)
-        self.back_button = xml.get_widget ("back_button")
-        self.back_button.connect("clicked",self.back)
+        xml.get_widget("cancel_button").connect("clicked", self.quit)
+        self.forward_button = xml.get_widget("forward_button")
+        self.forward_button.connect("clicked", self.forward)
+        self.back_button = xml.get_widget("back_button")
+        self.back_button.connect("clicked", self.back)
 
-        self.boolean_dialog = xml.get_widget ("boolean_dialog")
-        self.boolean_name_entry = xml.get_widget ("boolean_name_entry")
-        self.boolean_description_entry = xml.get_widget ("boolean_description_entry")
+        self.boolean_dialog = xml.get_widget("boolean_dialog")
+        self.boolean_name_entry = xml.get_widget("boolean_name_entry")
+        self.boolean_description_entry = xml.get_widget("boolean_description_entry")
 
-        self.pages={}
+        self.pages = {}
         for i in generate.USERS:
-            self.pages[i] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
-        self.pages[generate.RUSER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE,  self.ADMIN_PAGE, self.USER_TRANSITION_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
-        self.pages[generate.LUSER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
-        self.pages[generate.SANDBOX] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
-        self.pages[generate.EUSER] = [ self.SELECT_TYPE_PAGE, self.EXISTING_USER_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
+            self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+        self.pages[generate.RUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.ADMIN_PAGE, self.USER_TRANSITION_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+        self.pages[generate.LUSER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+        self.pages[generate.SANDBOX] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+        self.pages[generate.EUSER] = [self.SELECT_TYPE_PAGE, self.EXISTING_USER_PAGE, self.TRANSITION_PAGE, self.ROLE_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
 
         for i in generate.APPLICATIONS:
-            self.pages[i] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
-        self.pages[generate.USER] = [ self.SELECT_TYPE_PAGE, self.APP_PAGE, self.USER_TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE ]
+            self.pages[i] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
+        self.pages[generate.USER] = [self.SELECT_TYPE_PAGE, self.APP_PAGE, self.USER_TRANSITION_PAGE, self.IN_NET_PAGE, self.OUT_NET_PAGE, self.COMMON_APPS_PAGE, self.FILES_PAGE, self.BOOLEAN_PAGE, self.SELECT_DIR_PAGE]
 
         self.current_page = 0
         self.back_button.set_sensitive(0)
 
         self.network_buttons = {}
 
-        self.in_tcp_all_checkbutton = xml.get_widget ("in_tcp_all_checkbutton")
-        self.in_tcp_reserved_checkbutton = xml.get_widget ("in_tcp_reserved_checkbutton")
-        self.in_tcp_unreserved_checkbutton = xml.get_widget ("in_tcp_unreserved_checkbutton")
+        self.in_tcp_all_checkbutton = xml.get_widget("in_tcp_all_checkbutton")
+        self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton")
+        self.in_tcp_unreserved_checkbutton = xml.get_widget("in_tcp_unreserved_checkbutton")
         self.in_tcp_entry = self.xml.get_widget("in_tcp_entry")
-        self.network_buttons[self.in_tcp_all_checkbutton] = [ self.in_tcp_reserved_checkbutton, self.in_tcp_unreserved_checkbutton, self.in_tcp_entry ]
+        self.network_buttons[self.in_tcp_all_checkbutton] = [self.in_tcp_reserved_checkbutton, self.in_tcp_unreserved_checkbutton, self.in_tcp_entry]
 
-
-        self.out_tcp_all_checkbutton = xml.get_widget ("out_tcp_all_checkbutton")
-        self.out_tcp_reserved_checkbutton = xml.get_widget ("out_tcp_reserved_checkbutton")
-        self.out_tcp_unreserved_checkbutton = xml.get_widget ("out_tcp_unreserved_checkbutton")
+        self.out_tcp_all_checkbutton = xml.get_widget("out_tcp_all_checkbutton")
+        self.out_tcp_reserved_checkbutton = xml.get_widget("out_tcp_reserved_checkbutton")
+        self.out_tcp_unreserved_checkbutton = xml.get_widget("out_tcp_unreserved_checkbutton")
         self.out_tcp_entry = self.xml.get_widget("out_tcp_entry")
 
-        self.network_buttons[self.out_tcp_all_checkbutton] = [ self.out_tcp_entry ]
+        self.network_buttons[self.out_tcp_all_checkbutton] = [self.out_tcp_entry]
 
-        self.in_udp_all_checkbutton = xml.get_widget ("in_udp_all_checkbutton")
-        self.in_udp_reserved_checkbutton = xml.get_widget ("in_udp_reserved_checkbutton")
-        self.in_udp_unreserved_checkbutton = xml.get_widget ("in_udp_unreserved_checkbutton")
+        self.in_udp_all_checkbutton = xml.get_widget("in_udp_all_checkbutton")
+        self.in_udp_reserved_checkbutton = xml.get_widget("in_udp_reserved_checkbutton")
+        self.in_udp_unreserved_checkbutton = xml.get_widget("in_udp_unreserved_checkbutton")
         self.in_udp_entry = self.xml.get_widget("in_udp_entry")
 
-        self.network_buttons[self.in_udp_all_checkbutton] = [ self.in_udp_reserved_checkbutton, self.in_udp_unreserved_checkbutton, self.in_udp_entry ]
+        self.network_buttons[self.in_udp_all_checkbutton] = [self.in_udp_reserved_checkbutton, self.in_udp_unreserved_checkbutton, self.in_udp_entry]
 
-        self.out_udp_all_checkbutton = xml.get_widget ("out_udp_all_checkbutton")
+        self.out_udp_all_checkbutton = xml.get_widget("out_udp_all_checkbutton")
         self.out_udp_entry = self.xml.get_widget("out_udp_entry")
-        self.network_buttons[self.out_udp_all_checkbutton] = [ self.out_udp_entry ]
+        self.network_buttons[self.out_udp_all_checkbutton] = [self.out_udp_entry]
 
         for b in self.network_buttons.keys():
-            b.connect("clicked",self.network_all_clicked)
+            b.connect("clicked", self.network_all_clicked)
 
         self.boolean_treeview = self.xml.get_widget("boolean_treeview")
-        self.boolean_store = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING)
+        self.boolean_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
         self.boolean_treeview.set_model(self.boolean_store)
         self.boolean_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text=0)
         self.boolean_treeview.append_column(col)
-        col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text = 1)
+        col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=1)
         self.boolean_treeview.append_column(col)
 
         self.role_treeview = self.xml.get_widget("role_treeview")
@@ -279,28 +282,28 @@
         self.role_treeview.set_model(self.role_store)
         self.role_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
         self.role_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Role"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Role"), gtk.CellRendererText(), text=0)
         self.role_treeview.append_column(col)
 
         self.existing_user_treeview = self.xml.get_widget("existing_user_treeview")
         self.existing_user_store = gtk.ListStore(gobject.TYPE_STRING)
         self.existing_user_treeview.set_model(self.existing_user_store)
         self.existing_user_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Existing_User"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Existing_User"), gtk.CellRendererText(), text=0)
         self.existing_user_treeview.append_column(col)
 
         for i in self.all_roles:
             iter = self.role_store.append()
             self.role_store.set_value(iter, 0, i[:-2])
 
-        self.in_tcp_reserved_checkbutton = xml.get_widget ("in_tcp_reserved_checkbutton")
+        self.in_tcp_reserved_checkbutton = xml.get_widget("in_tcp_reserved_checkbutton")
 
         self.transition_treeview = self.xml.get_widget("transition_treeview")
         self.transition_store = gtk.ListStore(gobject.TYPE_STRING)
         self.transition_treeview.set_model(self.transition_store)
         self.transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
         self.transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0)
         self.transition_treeview.append_column(col)
 
         self.user_transition_treeview = self.xml.get_widget("user_transition_treeview")
@@ -308,7 +311,7 @@
         self.user_transition_treeview.set_model(self.user_transition_store)
         self.user_transition_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
         self.user_transition_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0)
         self.user_transition_treeview.append_column(col)
 
         for i in self.all_users:
@@ -322,7 +325,7 @@
         self.admin_treeview.set_model(self.admin_store)
         self.admin_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
         self.admin_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("Application"), gtk.CellRendererText(), text=0)
         self.admin_treeview.append_column(col)
 
         try:
@@ -333,7 +336,7 @@
             for a in sepolicy.interface.get_admin():
                 iter = self.admin_store.append()
                 self.admin_store.set_value(iter, 0, a)
-        except ValueError,e:
+        except ValueError, e:
             self.error(e.message)
 
     def confine_application(self):
@@ -367,19 +370,19 @@
         if self.pages[type][self.current_page] == self.SELECT_DIR_PAGE:
             outputdir = self.output_entry.get_text()
             if not os.path.isdir(outputdir):
-                self.error(_("%s must be a directory") % outputdir )
+                self.error(_("%s must be a directory") % outputdir)
                 return False
 
         if self.pages[type][self.current_page] == self.FINISH_PAGE:
             self.generate_policy()
-            self.xml.get_widget ("cancel_button").set_label(gtk.STOCK_CLOSE)
+            self.xml.get_widget("cancel_button").set_label(gtk.STOCK_CLOSE)
         else:
             self.current_page = self.current_page + 1
             self.notebook.set_current_page(self.pages[type][self.current_page])
             if self.pages[type][self.current_page] == self.FINISH_PAGE:
                 self.forward_button.set_label(gtk.STOCK_APPLY)
 
-    def back(self,arg):
+    def back(self, arg):
         type = self.get_type()
         if self.pages[type][self.current_page] == self.FINISH_PAGE:
             self.forward_button.set_label(gtk.STOCK_GO_FORWARD)
@@ -394,7 +397,7 @@
         for b in self.network_buttons[button]:
             b.set_sensitive(not active)
 
-    def verify(self, message, title="" ):
+    def verify(self, message, title=""):
         dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
                                 gtk.BUTTONS_YES_NO,
                                 message)
@@ -461,12 +464,12 @@
     def generate_policy(self, *args):
         outputdir = self.output_entry.get_text()
         try:
-            my_policy=generate.policy(self.get_name(), self.get_type())
+            my_policy = generate.policy(self.get_name(), self.get_type())
 
-            iter= self.boolean_store.get_iter_first()
+            iter = self.boolean_store.get_iter_first()
             while(iter):
                 my_policy.add_boolean(self.boolean_store.get_value(iter, 0), self.boolean_store.get_value(iter, 1))
-                iter= self.boolean_store.iter_next(iter)
+                iter = self.boolean_store.iter_next(iter)
 
             if self.get_type() in generate.APPLICATIONS:
                 my_policy.set_program(self.exec_entry.get_text())
@@ -509,13 +512,13 @@
             my_policy.set_out_tcp(self.out_tcp_all_checkbutton.get_active(), self.out_tcp_entry.get_text())
             my_policy.set_out_udp(self.out_udp_all_checkbutton.get_active(), self.out_udp_entry.get_text())
 
-            iter= self.store.get_iter_first()
+            iter = self.store.get_iter_first()
             while(iter):
                 if self.store.get_value(iter, 1) == FILE:
                     my_policy.add_file(self.store.get_value(iter, 0))
                 else:
                     my_policy.add_dir(self.store.get_value(iter, 0))
-                iter= self.store.iter_next(iter)
+                iter = self.store.iter_next(iter)
 
             self.info(my_policy.generate(outputdir))
             return False
@@ -526,15 +529,15 @@
         store, iter = self.view.get_selection().get_selected()
         if iter != None:
             store.remove(iter)
-            self.view.get_selection().select_path ((0,))
+            self.view.get_selection().select_path((0,))
 
     def delete_boolean(self, args):
         store, iter = self.boolean_treeview.get_selection().get_selected()
         if iter != None:
             store.remove(iter)
-            self.boolean_treeview.get_selection().select_path ((0,))
+            self.boolean_treeview.get_selection().select_path((0,))
 
-    def add_boolean(self,type):
+    def add_boolean(self, type):
         self.boolean_name_entry.set_text("")
         self.boolean_description_entry.set_text("")
         rc = self.boolean_dialog.run()
@@ -545,7 +548,7 @@
         self.boolean_store.set_value(iter, 0, self.boolean_name_entry.get_text())
         self.boolean_store.set_value(iter, 1, self.boolean_description_entry.get_text())
 
-    def __add(self,type):
+    def __add(self, type):
         rc = self.file_dialog.run()
         self.file_dialog.hide()
         if rc == gtk.RESPONSE_CANCEL:
@@ -592,9 +595,9 @@
         self.__add(DIR)
 
     def on_about_clicked(self, args):
-        dlg = xml.get_widget ("about_dialog")
-        dlg.run ()
-        dlg.hide ()
+        dlg = xml.get_widget("about_dialog")
+        dlg.run()
+        dlg.hide()
 
     def quit(self, args):
         gtk.main_quit()
@@ -605,15 +608,15 @@
         self.druid = self.xml.get_widget("druid")
         self.type = 0
         self.name_entry = self.xml.get_widget("name_entry")
-        self.name_entry.connect("insert_text",self.on_name_entry_changed)
-        self.name_entry.connect("focus_out_event",self.on_focus_out_event)
+        self.name_entry.connect("insert_text", self.on_name_entry_changed)
+        self.name_entry.connect("focus_out_event", self.on_focus_out_event)
         self.exec_entry = self.xml.get_widget("exec_entry")
         self.exec_button = self.xml.get_widget("exec_button")
         self.init_script_entry = self.xml.get_widget("init_script_entry")
         self.init_script_button = self.xml.get_widget("init_script_button")
         self.output_entry = self.xml.get_widget("output_entry")
         self.output_entry.set_text(os.getcwd())
-        self.xml.get_widget("output_button").connect("clicked",self.output_button_clicked)
+        self.xml.get_widget("output_button").connect("clicked", self.output_button_clicked)
 
         self.xwindows_user_radiobutton = self.xml.get_widget("xwindows_user_radiobutton")
         self.terminal_user_radiobutton = self.xml.get_widget("terminal_user_radiobutton")
@@ -641,10 +644,10 @@
 
         self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
         self.view.set_model(self.store)
-        col = gtk.TreeViewColumn("",  gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
         col.set_resizable(True)
         self.view.append_column(col)
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
     def output_button_clicked(self, *args):
         self.file_dialog.set_title(_("Select directory to generate policy files in"))
@@ -712,7 +715,7 @@
             return True
 
     def on_name_page_next(self, *args):
-        name=self.name_entry.get_text()
+        name = self.name_entry.get_text()
         if not name.isalnum():
             self.error(_("You must add a name made up of letters and numbers and containing no spaces."))
             return True
@@ -730,7 +733,7 @@
             if exe == "":
                 self.error(_("You must enter a executable"))
                 return True
-            policy=generate.policy(name, self.get_type())
+            policy = generate.policy(name, self.get_type())
             policy.set_program(exe)
             policy.gen_writeable()
             policy.gen_symbols()
@@ -762,7 +765,7 @@
         gtk.main()
 
 if __name__ == "__main__":
-    signal.signal (signal.SIGINT, signal.SIG_DFL)
+    signal.signal(signal.SIGINT, signal.SIG_DFL)
 
     app = childWindow()
     app.stand_alone()
diff --git a/policycoreutils/gui/portsPage.py b/policycoreutils/gui/portsPage.py
index bfb4e36..8e74ac0 100644
--- a/policycoreutils/gui/portsPage.py
+++ b/policycoreutils/gui/portsPage.py
@@ -24,7 +24,7 @@
 import sys
 import seobject
 import commands
-from semanagePage import *;
+from semanagePage import *
 
 ##
 ## I18N
@@ -41,12 +41,14 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 class portsPage(semanagePage):
+
     def __init__(self, xml):
         semanagePage.__init__(self, xml, "ports", _("Network Port"))
         xml.signal_connect("on_group_clicked", self.on_group_clicked)
@@ -69,7 +71,7 @@
         self.load()
 
     def filter_changed(self, *arg):
-        filter =  arg[0].get_text()
+        filter = arg[0].get_text()
         if filter != self.filter:
             if self.edit:
                 self.load(filter)
@@ -77,37 +79,37 @@
                 self.group_load(filter)
 
     def init_store(self):
-        self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING , gobject.TYPE_STRING)
+        self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
         self.view.set_model(self.store)
         self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
 
         self.view.set_search_equal_func(self.search)
-        col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text = TYPE_COL)
+        col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text=TYPE_COL)
         col.set_sort_column_id(TYPE_COL)
         col.set_resizable(True)
         self.view.append_column(col)
         self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING)
 
-        col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text = PROTOCOL_COL)
+        col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text=PROTOCOL_COL)
         col.set_sort_column_id(PROTOCOL_COL)
         col.set_resizable(True)
         self.view.append_column(col)
 
-        self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text = MLS_COL)
+        self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text=MLS_COL)
         self.mls_col.set_resizable(True)
         self.mls_col.set_sort_column_id(MLS_COL)
         self.view.append_column(self.mls_col)
 
-        col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text = PORT_COL)
+        col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text=PORT_COL)
         col.set_sort_column_id(PORT_COL)
         col.set_resizable(True)
         self.view.append_column(col)
-        self.store.set_sort_func(PORT_COL,self.sort_int, "")
+        self.store.set_sort_func(PORT_COL, self.sort_int, "")
 
     def sort_int(self, treemodel, iter1, iter2, user_data):
         try:
-            p1 = int(treemodel.get_value(iter1,PORT_COL).split('-')[0])
-            p2 = int(treemodel.get_value(iter2,PORT_COL).split('-')[0])
+            p1 = int(treemodel.get_value(iter1, PORT_COL).split('-')[0])
+            p2 = int(treemodel.get_value(iter2, PORT_COL).split('-')[0])
             if p1 > p2:
                 return 1
             if p1 == p2:
@@ -116,8 +118,8 @@
         except:
             return 0
 
-    def load(self,filter = ""):
-        self.filter=filter
+    def load(self, filter=""):
+        self.filter = filter
         self.port = seobject.portRecords()
         dict = self.port.get_all(self.local)
         keys = dict.keys()
@@ -135,10 +137,10 @@
             self.store.set_value(iter, TYPE_COL, dict[k][0])
             self.store.set_value(iter, PROTOCOL_COL, k[2])
             self.store.set_value(iter, MLS_COL, dict[k][1])
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
-    def group_load(self, filter = ""):
-        self.filter=filter
+    def group_load(self, filter=""):
+        self.filter = filter
         self.port = seobject.portRecords()
         dict = self.port.get_all_by_type(self.local)
         keys = dict.keys()
@@ -146,14 +148,14 @@
         self.store.clear()
         for k in keys:
             ports_string = ", ".join(dict[k])
-            if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter) ):
+            if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter)):
                 continue
             iter = self.store.append()
             self.store.set_value(iter, TYPE_COL, k[0])
             self.store.set_value(iter, PROTOCOL_COL, k[1])
             self.store.set_value(iter, PORT_COL, ports_string)
             self.store.set_value(iter, MLS_COL, "")
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
     def propertiesDialog(self):
         if self.edit:
@@ -169,7 +171,7 @@
         protocol = store.get_value(iter, PROTOCOL_COL)
         liststore = self.ports_protocol_combo.get_model()
         iter = liststore.get_iter_first()
-        while iter != None and liststore.get_value(iter,0) != protocol:
+        while iter != None and liststore.get_value(iter, 0) != protocol:
             iter = liststore.iter_next(iter)
         if iter != None:
             self.ports_protocol_combo.set_active_iter(iter)
@@ -192,7 +194,7 @@
             if rc != 0:
                 return self.error(out)
             store.remove(iter)
-            self.view.get_selection().select_path ((0,))
+            self.view.get_selection().select_path((0,))
         except ValueError, e:
             self.error(e.args[0])
 
@@ -204,11 +206,11 @@
             port_number = "1"
         for i in port_number.split("-"):
             if not i.isdigit():
-                self.error(_("Port number \"%s\" is not valid.  0 < PORT_NUMBER < 65536 ") % port_number )
+                self.error(_("Port number \"%s\" is not valid.  0 < PORT_NUMBER < 65536 ") % port_number)
                 return False
         list_model = self.ports_protocol_combo.get_model()
         iter = self.ports_protocol_combo.get_active_iter()
-        protocol = list_model.get_value(iter,0)
+        protocol = list_model.get_value(iter, 0)
         self.wait()
         (rc, out) = commands.getstatusoutput("semanage port -a -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
         self.ready()
@@ -228,7 +230,7 @@
         port_number = self.ports_number_entry.get_text().strip()
         list_model = self.ports_protocol_combo.get_model()
         iter = self.ports_protocol_combo.get_active_iter()
-        protocol = list_model.get_value(iter,0)
+        protocol = list_model.get_value(iter, 0)
         self.wait()
         (rc, out) = commands.getstatusoutput("semanage port -m -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
         self.ready()
diff --git a/policycoreutils/gui/semanagePage.py b/policycoreutils/gui/semanagePage.py
index 3a0e478..5d7f2cf 100644
--- a/policycoreutils/gui/semanagePage.py
+++ b/policycoreutils/gui/semanagePage.py
@@ -27,7 +27,7 @@
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
@@ -35,16 +35,19 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 def idle_func():
     while gtk.events_pending():
         gtk.main_iteration()
 
+
 class semanagePage:
+
     def __init__(self, xml, name, description):
         self.xml = xml
         self.window = self.xml.get_widget("mainWindow").get_root_window()
@@ -54,13 +57,13 @@
         self.local = False
         self.view = xml.get_widget("%sView" % name)
         self.dialog = xml.get_widget("%sDialog" % name)
-        self.filter_entry = xml.get_widget("%sFilterEntry" % name )
+        self.filter_entry = xml.get_widget("%sFilterEntry" % name)
         self.filter_entry.connect("focus_out_event", self.filter_changed)
         self.filter_entry.connect("activate", self.filter_changed)
 
         self.view.connect("row_activated", self.rowActivated)
         self.view.get_selection().connect("changed", self.itemSelected)
-        self.description = description;
+        self.description = description
 
     def wait(self):
         self.window.set_cursor(self.busy_cursor)
@@ -77,21 +80,21 @@
         return
 
     def filter_changed(self, *arg):
-        filter =  arg[0].get_text()
+        filter = arg[0].get_text()
         if filter != self.filter:
             self.load(filter)
 
     def search(self, model, col, key, i):
         sort_col = self.store.get_sort_column_id()[0]
-        val = model.get_value(i,sort_col)
+        val = model.get_value(i, sort_col)
         if val.lower().startswith(key.lower()):
             return False
         return True
 
     def match(self, target, filter):
         try:
-            f=filter.lower()
-            t=target.lower()
+            f = filter.lower()
+            t = target.lower()
             if t.find(f) >= 0:
                 return True
         except:
@@ -101,7 +104,7 @@
     def rowActivated(self, view, row, Column):
         self.propertiesDialog()
 
-    def verify(self, message, title="" ):
+    def verify(self, message, title=""):
         dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
                                 gtk.BUTTONS_YES_NO,
                                 message)
@@ -134,11 +137,11 @@
         self.dialog.set_title(_("Add %s" % self.description))
         self.dialog.set_position(gtk.WIN_POS_MOUSE)
 
-        while self.dialog.run() ==  gtk.RESPONSE_OK:
+        while self.dialog.run() == gtk.RESPONSE_OK:
             try:
                 if self.add() == False:
                     continue
-                break;
+                break
             except ValueError, e:
                 self.error(e.args[0])
         self.dialog.hide()
@@ -147,11 +150,11 @@
         self.dialogInit()
         self.dialog.set_title(_("Modify %s" % self.description))
         self.dialog.set_position(gtk.WIN_POS_MOUSE)
-        while self.dialog.run() ==  gtk.RESPONSE_OK:
+        while self.dialog.run() == gtk.RESPONSE_OK:
             try:
                 if self.modify() == False:
                     continue
-                break;
+                break
             except ValueError, e:
                 self.error(e.args[0])
         self.dialog.hide()
diff --git a/policycoreutils/gui/statusPage.py b/policycoreutils/gui/statusPage.py
index 02685f2..991d8f3 100644
--- a/policycoreutils/gui/statusPage.py
+++ b/policycoreutils/gui/statusPage.py
@@ -31,7 +31,7 @@
 ENFORCING = 1
 PERMISSIVE = 0
 DISABLED = -1
-modearray = ( "disabled", "permissive",  "enforcing" )
+modearray = ("disabled", "permissive", "enforcing")
 
 SELINUXDIR = "/etc/selinux/"
 RELABELFILE = "/.autorelabel"
@@ -39,7 +39,7 @@
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
@@ -50,7 +50,9 @@
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 class statusPage:
+
     def __init__(self, xml):
         self.xml = xml
         self.needRelabel = False
@@ -66,15 +68,15 @@
         self.relabel_checkbutton.set_active(self.is_relabel())
         self.relabel_checkbutton.connect("toggled", self.on_relabel_toggle)
         if self.get_current_mode() == ENFORCING or self.get_current_mode() == PERMISSIVE:
-                self.currentOptionMenu.append_text(_("Permissive"))
-                self.currentOptionMenu.append_text(_("Enforcing"))
-                self.currentOptionMenu.set_active(self.get_current_mode())
-                self.currentOptionMenu.connect("changed", self.set_current_mode)
-                self.currentOptionMenu.set_sensitive(True)
+            self.currentOptionMenu.append_text(_("Permissive"))
+            self.currentOptionMenu.append_text(_("Enforcing"))
+            self.currentOptionMenu.set_active(self.get_current_mode())
+            self.currentOptionMenu.connect("changed", self.set_current_mode)
+            self.currentOptionMenu.set_sensitive(True)
         else:
-                self.currentOptionMenu.append_text(_("Disabled"))
-                self.currentOptionMenu.set_active(0)
-                self.currentOptionMenu.set_sensitive(False)
+            self.currentOptionMenu.append_text(_("Disabled"))
+            self.currentOptionMenu.set_active(0)
+            self.currentOptionMenu.set_sensitive(False)
 
         if self.read_selinux_config() == None:
             self.selinuxsupport = False
@@ -102,15 +104,15 @@
         else:
             return DISABLED
 
-    def set_current_mode(self,menu):
+    def set_current_mode(self, menu):
         selinux.security_setenforce(menu.get_active() == 1)
 
     def is_relabel(self):
         return os.access(RELABELFILE, os.F_OK) != 0
 
-    def on_relabel_toggle(self,button):
+    def on_relabel_toggle(self, button):
         if button.get_active():
-            fd = open(RELABELFILE,"w")
+            fd = open(RELABELFILE, "w")
             fd.close()
         else:
             if os.access(RELABELFILE, os.F_OK) != 0:
@@ -136,7 +138,7 @@
 
             self.relabel_checkbutton.set_active(True)
 
-        self.write_selinux_config(modearray[enabled], type )
+        self.write_selinux_config(modearray[enabled], type)
         self.typeHistory = menu.get_active()
 
     def enabled_changed(self, combo):
@@ -154,11 +156,11 @@
                 return None
             self.relabel_checkbutton.set_active(True)
 
-        self.write_selinux_config(modearray[enabled], type )
+        self.write_selinux_config(modearray[enabled], type)
         self.enabled = enabled
 
     def write_selinux_config(self, enforcing, type):
-        path = selinux.selinux_path() + "config" 
+        path = selinux.selinux_path() + "config"
         backup_path = path + ".bck"
         fd = open(path)
         lines = fd.readlines()
@@ -183,7 +185,7 @@
             self.initEnabled = False
             pass
         self.enabled = self.initEnabled
-        self.enabledOptionMenu.set_active(self.enabled + 1 )
+        self.enabledOptionMenu.set_active(self.enabled + 1)
 
         self.types = []
 
@@ -191,12 +193,12 @@
         current = n
 
         for i in os.listdir(SELINUXDIR):
-            if os.path.isdir(SELINUXDIR+i) and os.path.isdir(SELINUXDIR+i+"/policy"):
+            if os.path.isdir(SELINUXDIR + i) and os.path.isdir(SELINUXDIR + i + "/policy"):
                 self.types.append(i)
                 self.selinuxTypeOptionMenu.append_text(i)
                 if i == self.initialtype:
                     current = n
-                n = n+1
+                n = n + 1
         self.selinuxTypeOptionMenu.set_active(current)
         self.typeHistory = current
 
diff --git a/policycoreutils/gui/system-config-selinux.py b/policycoreutils/gui/system-config-selinux.py
index bc3027e..7d342d0 100644
--- a/policycoreutils/gui/system-config-selinux.py
+++ b/policycoreutils/gui/system-config-selinux.py
@@ -28,7 +28,7 @@
 except RuntimeError, e:
     print "system-config-selinux:", e
     print "This is a graphical application and requires DISPLAY to be set."
-    sys.exit (1)
+    sys.exit(1)
 
 import gtk.glade
 import os
@@ -46,7 +46,7 @@
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -55,7 +55,7 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
@@ -67,18 +67,19 @@
 sys.path.append('/usr/share/system-config-selinux')
 
 
-
 ##
 ## Pull in the Glade file
 ##
 if os.access("system-config-selinux.glade", os.F_OK):
-    xml = gtk.glade.XML ("system-config-selinux.glade", domain=PROGNAME)
+    xml = gtk.glade.XML("system-config-selinux.glade", domain=PROGNAME)
 else:
-    xml = gtk.glade.XML ("/usr/share/system-config-selinux/system-config-selinux.glade", domain=PROGNAME)
+    xml = gtk.glade.XML("/usr/share/system-config-selinux/system-config-selinux.glade", domain=PROGNAME)
+
 
 class childWindow:
+
     def __init__(self):
-        self.tabs=[]
+        self.tabs = []
         self.xml = xml
         xml.signal_connect("on_quit_activate", self.destroy)
         xml.signal_connect("on_delete_clicked", self.delete)
@@ -93,8 +94,8 @@
                 self.add_page(loginsPage.loginsPage(xml))
                 self.add_page(usersPage.usersPage(xml))
                 self.add_page(portsPage.portsPage(xml))
-                self.add_page(modulesPage.modulesPage(xml)) # modules
-                self.add_page(domainsPage.domainsPage(xml)) # domains
+                self.add_page(modulesPage.modulesPage(xml))  # modules
+                self.add_page(domainsPage.domainsPage(xml))  # domains
             except ValueError, e:
                 self.error(e.message)
 
@@ -121,6 +122,7 @@
 
     def policy(self, args):
         os.spawnl(os.P_NOWAIT, "/usr/share/system-config-selinux/semanagegui.py")
+
     def logging(self, args):
         os.spawnl(os.P_NOWAIT, "/usr/bin/seaudit")
 
@@ -137,9 +139,9 @@
         self.tabs[self.notebook.get_current_page()].on_local_clicked(button)
 
     def on_about_activate(self, args):
-        dlg = xml.get_widget ("aboutWindow")
-        dlg.run ()
-        dlg.hide ()
+        dlg = xml.get_widget("aboutWindow")
+        dlg.run()
+        dlg.hide()
 
     def destroy(self, args):
         gtk.main_quit()
@@ -158,7 +160,6 @@
             self.notebook.set_current_page(0)
             self.use_menus(self.tabs[0].use_menus())
 
-
     def setupScreen(self):
         # Bring in widgets from glade file.
         self.mainWindow = self.xml.get_widget("mainWindow")
@@ -167,14 +168,14 @@
         self.view.get_selection().connect("changed", self.itemSelected)
         self.store = gtk.ListStore(gobject.TYPE_STRING)
         self.view.set_model(self.store)
-        col = gtk.TreeViewColumn("",  gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn("", gtk.CellRendererText(), text=0)
         col.set_resizable(True)
         self.view.append_column(col)
 
         for page in self.tabs:
             iter = self.store.append()
             self.store.set_value(iter, 0, page.get_description())
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
     def stand_alone(self):
         desktopName = _("Configue SELinux")
@@ -187,7 +188,7 @@
         gtk.main()
 
 if __name__ == "__main__":
-    signal.signal (signal.SIGINT, signal.SIG_DFL)
+    signal.signal(signal.SIGINT, signal.SIG_DFL)
 
     app = childWindow()
     app.stand_alone()
diff --git a/policycoreutils/gui/usersPage.py b/policycoreutils/gui/usersPage.py
index 93804ac..abf8d3b 100644
--- a/policycoreutils/gui/usersPage.py
+++ b/policycoreutils/gui/usersPage.py
@@ -24,12 +24,12 @@
 import sys
 import commands
 import seobject
-from semanagePage import *;
+from semanagePage import *
 
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
@@ -39,7 +39,9 @@
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 class usersPage(semanagePage):
+
     def __init__(self, xml):
         semanagePage.__init__(self, xml, "users", _("SELinux User"))
 
@@ -47,16 +49,16 @@
         self.view.set_model(self.store)
         self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)
 
-        col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text = 0)
+        col = gtk.TreeViewColumn(_("SELinux\nUser"), gtk.CellRendererText(), text=0)
         col.set_sort_column_id(0)
         col.set_resizable(True)
         self.view.append_column(col)
 
-        col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text = 1)
+        col = gtk.TreeViewColumn(_("MLS/\nMCS Range"), gtk.CellRendererText(), text=1)
         col.set_resizable(True)
         self.view.append_column(col)
 
-        col = gtk.TreeViewColumn(_("SELinux Roles"), gtk.CellRendererText(), text = 2)
+        col = gtk.TreeViewColumn(_("SELinux Roles"), gtk.CellRendererText(), text=2)
         col.set_resizable(True)
         self.view.append_column(col)
 
@@ -65,8 +67,8 @@
         self.mlsRangeEntry = xml.get_widget("mlsRangeEntry")
         self.selinuxRolesEntry = xml.get_widget("selinuxRolesEntry")
 
-    def load(self, filter = ""):
-        self.filter=filter
+    def load(self, filter=""):
+        self.filter = filter
         self.user = seobject.seluserRecords()
         dict = self.user.get_all()
         keys = dict.keys()
@@ -81,11 +83,11 @@
             self.store.set_value(iter, 0, k)
             self.store.set_value(iter, 1, range)
             self.store.set_value(iter, 2, dict[k][3])
-        self.view.get_selection().select_path ((0,))
+        self.view.get_selection().select_path((0,))
 
     def delete(self):
         if semanagePage.delete(self) == gtk.RESPONSE_NO:
-                return None
+            return None
 
     def dialogInit(self):
         store, iter = self.view.get_selection().get_selected()
@@ -106,7 +108,7 @@
         roles = self.selinuxRolesEntry.get_text()
 
         self.wait()
-        (rc, out) = commands.getstatusoutput("semanage user -a -R '%s' -r %s %s" %  (roles, range, user))
+        (rc, out) = commands.getstatusoutput("semanage user -a -R '%s' -r %s %s" % (roles, range, user))
         self.ready()
         if rc != 0:
             self.error(out)
@@ -122,7 +124,7 @@
         roles = self.selinuxRolesEntry.get_text()
 
         self.wait()
-        (rc, out) = commands.getstatusoutput("semanage user -m -R '%s' -r %s %s" %  (roles, range, user))
+        (rc, out) = commands.getstatusoutput("semanage user -m -R '%s' -r %s %s" % (roles, range, user))
         self.ready()
 
         if rc != 0:
@@ -133,17 +135,17 @@
     def delete(self):
         store, iter = self.view.get_selection().get_selected()
         try:
-            user=store.get_value(iter, 0)
+            user = store.get_value(iter, 0)
             if user == "root" or user == "user_u":
                 raise ValueError(_("SELinux user '%s' is required") % user)
 
             self.wait()
-            (rc, out) = commands.getstatusoutput("semanage user -d %s" %  user)
+            (rc, out) = commands.getstatusoutput("semanage user -d %s" % user)
             self.ready()
             if rc != 0:
                 self.error(out)
                 return False
             store.remove(iter)
-            self.view.get_selection().select_path ((0,))
+            self.view.get_selection().select_path((0,))
         except ValueError, e:
             self.error(e.args[0])
diff --git a/policycoreutils/mcstrans/share/util/mlscolor-test b/policycoreutils/mcstrans/share/util/mlscolor-test
index 73243e8..7b8d809 100644
--- a/policycoreutils/mcstrans/share/util/mlscolor-test
+++ b/policycoreutils/mcstrans/share/util/mlscolor-test
@@ -1,14 +1,15 @@
 #!/usr/bin/python -E
-import sys, re
+import sys
+import re
 from selinux import *
 verbose = 0
-errors=0
+errors = 0
 
 if len(sys.argv) > 1 and sys.argv[1] == "-v":
     verbose = 1
-    
+
 for arg in sys.argv[1:]:
-    f=open(arg, 'r')
+    f = open(arg, 'r')
     for line in f:
         if line.startswith('#'):
             continue
@@ -16,7 +17,7 @@
             continue
         line = line.rstrip('\n')
 #       print line
-        context,expected=line.split("=");
+        context, expected = line.split("=")
         rc, raw = selinux_trans_to_raw_context(context)
         if rc < 0:
             print "Unable to get raw context of '%s'" % (context)
@@ -29,15 +30,14 @@
             continue
         colors = colors.rstrip()
         if colors != expected:
-            print "For '%s' got\n\t'%s' expected\n\t'%s'" % (context,colors,expected)
+            print "For '%s' got\n\t'%s' expected\n\t'%s'" % (context, colors, expected)
             errors += 1
             continue
     f.close()
 
 s = "s"
-if errors == 1: s = ""
+if errors == 1:
+    s = ""
 print "mlscolor-test done with %d error%s" % (errors, s)
 
 sys.exit(errors)
-
-
diff --git a/policycoreutils/mcstrans/share/util/mlstrans-test b/policycoreutils/mcstrans/share/util/mlstrans-test
index ac86391..f854f7b 100644
--- a/policycoreutils/mcstrans/share/util/mlstrans-test
+++ b/policycoreutils/mcstrans/share/util/mlstrans-test
@@ -1,8 +1,11 @@
 #!/usr/bin/python -E
-import sys, re
+import sys
+import re
 from selinux import *
 verbose = 0
-errors=0
+errors = 0
+
+
 def untrans(trans, val):
     global errors, verbose
     (rc, raw) = selinux_trans_to_raw_context(trans)
@@ -12,22 +15,23 @@
     else:
         if verbose:
             print "untrans: %s -> %s != %s SUCCESS" % (trans, raw, val)
-        
+
+
 def trans(raw, val):
     global errors, verbose
     (rc, trans) = selinux_raw_to_trans_context(raw)
     if trans != val:
-        print "trans: '%s' -> '%s' != '%s' FAILED" % (raw,trans,  val)
+        print "trans: '%s' -> '%s' != '%s' FAILED" % (raw, trans, val)
         errors += 1
     else:
         if verbose:
-            print "trans: %s -> %s != %s SUCCESS" % (raw, trans,  val)
+            print "trans: %s -> %s != %s SUCCESS" % (raw, trans, val)
 
 if len(sys.argv) > 1 and sys.argv[1] == "-v":
     verbose = 1
-    
+
 for arg in sys.argv[1:]:
-    f=open(arg, 'r')
+    f = open(arg, 'r')
     for line in f:
         if line.startswith('#'):
             continue
@@ -36,18 +40,17 @@
         line = line.rstrip('\n')
 #       print line
         if (line.find("==") != -1):
-            t,r=line.split("==");
+            t, r = line.split("==")
             untrans("a:b:c:" + t, "a:b:c:" + r)
             trans("a:b:c:" + r, "a:b:c:" + t)
         else:
-            t,r=line.split("=");
+            t, r = line.split("=")
             untrans("a:b:c:" + t, "a:b:c:" + r)
     f.close()
 
 s = "s"
-if errors == 1: s = ""
+if errors == 1:
+    s = ""
 print "mlstrans-test done with %d error%s" % (errors, s)
 
 sys.exit(errors)
-
-
diff --git a/policycoreutils/newrole/newrole.c b/policycoreutils/newrole/newrole.c
index 1882cc8..65a945d 100644
--- a/policycoreutils/newrole/newrole.c
+++ b/policycoreutils/newrole/newrole.c
@@ -546,18 +546,27 @@
 	if (!uid) return 0;
 
 	capng_setpid(getpid());
-	capng_clear(CAPNG_SELECT_BOTH);
-	if (capng_lock() < 0) 
+	capng_clear(CAPNG_SELECT_CAPS);
+
+	if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
+		fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
 		return -1;
+	}
 
 	/* Change uid */
 	if (setresuid(uid, uid, uid)) {
 		fprintf(stderr, _("Error changing uid, aborting.\n"));
 		return -1;
 	}
+
+	if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) {
+		fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
+		return -1;
+	}
+
 	if (! full) 
 		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_AUDIT_WRITE);
-	return capng_apply(CAPNG_SELECT_BOTH);
+	return capng_apply(CAPNG_SELECT_CAPS);
 }
 #elif defined(NAMESPACE_PRIV)
 /**
@@ -575,20 +584,32 @@
  */
 static int drop_capabilities(int full)
 {
-	capng_setpid(getpid());
-	capng_clear(CAPNG_SELECT_BOTH);
-	if (capng_lock() < 0) 
-		return -1;
-
 	uid_t uid = getuid();
+	if (!uid) return 0;
+
+	capng_setpid(getpid());
+	capng_clear(CAPNG_SELECT_CAPS);
+
+	if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
+		fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
+		return -1;
+	}
+
 	/* Change uid */
 	if (setresuid(uid, uid, uid)) {
 		fprintf(stderr, _("Error changing uid, aborting.\n"));
 		return -1;
 	}
+
+	if (prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0) < 0) {
+		fprintf(stderr, _("Error resetting KEEPCAPS, aborting\n"));
+		return -1;
+	}
+
 	if (! full) 
-		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_SETPCAP, -1);
-	return capng_apply(CAPNG_SELECT_BOTH);
+		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SYS_ADMIN , CAP_FOWNER , CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_AUDIT_WRITE, -1);
+	
+	return capng_apply(CAPNG_SELECT_CAPS);
 }
 
 #else
@@ -679,7 +700,7 @@
 		       security_context_t * tty_context,
 		       security_context_t * new_tty_context)
 {
-	int fd;
+	int fd, rc;
 	int enforcing = security_getenforce();
 	security_context_t tty_con = NULL;
 	security_context_t new_tty_con = NULL;
@@ -698,7 +719,13 @@
 		fprintf(stderr, _("Error!  Could not open %s.\n"), ttyn);
 		return fd;
 	}
-	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+	/* this craziness is to make sure we cann't block on open and deadlock */
+	rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+	if (rc) {
+		fprintf(stderr, _("Error!  Could not clear O_NONBLOCK on %s\n"), ttyn);
+		close(fd);
+		return rc;
+	}
 
 	if (fgetfilecon(fd, &tty_con) < 0) {
 		fprintf(stderr, _("%s!  Could not get current context "
@@ -1009,9 +1036,9 @@
 	int fd;
 	pid_t childPid = 0;
 	char *shell_argv0 = NULL;
+	int rc;
 
 #ifdef USE_PAM
-	int rc;
 	int pam_status;		/* pam return code */
 	pam_handle_t *pam_handle;	/* opaque handle used by all PAM functions */
 
@@ -1225,15 +1252,23 @@
 		fd = open(ttyn, O_RDWR | O_NONBLOCK);
 		if (fd != 0)
 			goto err_close_pam;
-		fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+		rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+		if (rc)
+			goto err_close_pam;
+
 		fd = open(ttyn, O_RDWR | O_NONBLOCK);
 		if (fd != 1)
 			goto err_close_pam;
-		fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+		rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+		if (rc)
+			goto err_close_pam;
+
 		fd = open(ttyn, O_RDWR | O_NONBLOCK);
 		if (fd != 2)
 			goto err_close_pam;
-		fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+		rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
+		if (rc)
+			goto err_close_pam;
 
 	}
 	/*
@@ -1267,19 +1302,24 @@
 	}
 #endif
 
-	if (send_audit_message(1, old_context, new_context, ttyn))
+	if (send_audit_message(1, old_context, new_context, ttyn)) {
+		fprintf(stderr, _("Failed to send audit message"));
 		goto err_close_pam_session;
+	}
 	freecon(old_context); old_context=NULL;
 	freecon(new_context); new_context=NULL;
 
 #ifdef NAMESPACE_PRIV
-	if (transition_to_caller_uid())
+	if (transition_to_caller_uid()) {
+		fprintf(stderr, _("Failed to transition to namespace\n"));
 		goto err_close_pam_session;
+	}
 #endif
 
-	if (drop_capabilities(TRUE))
+	if (drop_capabilities(TRUE)) {
+		fprintf(stderr, _("Failed to drop capabilities %m\n"));
 		goto err_close_pam_session;
-
+	}
 	/* Handle environment changes */
 	if (restore_environment(preserve_environment, old_environ, &pw)) {
 		fprintf(stderr, _("Unable to restore the environment, "
diff --git a/policycoreutils/sandbox/sandbox b/policycoreutils/sandbox/sandbox
index 3678c5d..f40de10 100644
--- a/policycoreutils/sandbox/sandbox
+++ b/policycoreutils/sandbox/sandbox
@@ -20,12 +20,19 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
 
-import os, stat, sys, socket, random, fcntl, shutil, re, subprocess
+import os
+import stat
+import sys
+import socket
+import random
+import fcntl
+import shutil
+import re
+import subprocess
 import selinux
 import signal
 from tempfile import mkdtemp
 import pwd
-import commands
 import sepolicy
 
 PROGNAME = "policycoreutils"
@@ -36,13 +43,16 @@
 gettext.textdomain(PROGNAME)
 
 try:
-       gettext.install(PROGNAME,
-                       localedir = "/usr/share/locale",
-                       unicode=False,
-                       codeset = 'utf-8')
+    gettext.install(PROGNAME,
+                    localedir="/usr/share/locale",
+                    codeset='utf-8')
 except IOError:
-       import __builtin__
-       __builtin__.__dict__['_'] = unicode
+    try:
+        import builtins
+        builtins.__dict__['_'] = str
+    except ImportError:
+        import __builtin__
+        __builtin__.__dict__['_'] = unicode
 
 DEFAULT_WINDOWSIZE = "1000x700"
 DEFAULT_TYPE = "sandbox_t"
@@ -51,123 +61,136 @@
 
 random.seed(None)
 
+
 def sighandler(signum, frame):
-    signal.signal(signum,  signal.SIG_IGN)
+    signal.signal(signum, signal.SIG_IGN)
     os.kill(0, signum)
     raise KeyboardInterrupt
 
+
 def setup_sighandlers():
-    signal.signal(signal.SIGHUP,  sighandler)
+    signal.signal(signal.SIGHUP, sighandler)
     signal.signal(signal.SIGQUIT, sighandler)
     signal.signal(signal.SIGTERM, sighandler)
 
+
 def error_exit(msg):
     sys.stderr.write("%s: " % sys.argv[0])
     sys.stderr.write("%s\n" % msg)
     sys.stderr.flush()
     sys.exit(1)
 
+
 def copyfile(file, srcdir, dest):
-       import re
-       if file.startswith(srcdir):
-              dname = os.path.dirname(file)
-              bname = os.path.basename(file)
-              if dname == srcdir:
-                     dest = dest + "/" + bname
-              else:
-                     newdir = re.sub(srcdir, dest, dname)
-                     if not os.path.exists(newdir):
-                            os.makedirs(newdir)
-                     dest = newdir + "/" + bname
+    import re
+    if file.startswith(srcdir):
+        dname = os.path.dirname(file)
+        bname = os.path.basename(file)
+        if dname == srcdir:
+            dest = dest + "/" + bname
+        else:
+            newdir = re.sub(srcdir, dest, dname)
+            if not os.path.exists(newdir):
+                os.makedirs(newdir)
+            dest = newdir + "/" + bname
 
-              try:
-                     if os.path.isdir(file):
-                            shutil.copytree(file, dest)
-                     else:
-                            shutil.copy2(file, dest)
+        try:
+            if os.path.isdir(file):
+                shutil.copytree(file, dest)
+            else:
+                shutil.copy2(file, dest)
 
-              except shutil.Error, elist:
-                     for e in elist.message:
-                            sys.stderr.write(e[2])
-                     
-              SAVE_FILES[file] = (dest, os.path.getmtime(dest))
+        except shutil.Error as elist:
+            for e in elist.message:
+                sys.stderr.write(e[2])
+
+        SAVE_FILES[file] = (dest, os.path.getmtime(dest))
+
 
 def savefile(new, orig, X_ind):
-       copy = False
-       if(X_ind):
-              import gtk
-              dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
-                                      gtk.BUTTONS_YES_NO,
-                                      _("Do you want to save changes to '%s' (Y/N): ") % orig)
-              dlg.set_title(_("Sandbox Message"))
-              dlg.set_position(gtk.WIN_POS_MOUSE)
-              dlg.show_all()
-              rc = dlg.run()
-              dlg.destroy()
-              if rc == gtk.RESPONSE_YES:
-                     copy = True
-       else:
-              ans = raw_input(_("Do you want to save changes to '%s' (y/N): ") % orig)
-              if(re.match(_("[yY]"),ans)):
-                     copy = True
-       if(copy):
-              shutil.copy2(new,orig)
+    copy = False
+    if(X_ind):
+        import gtk
+        dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,
+                                gtk.BUTTONS_YES_NO,
+                                _("Do you want to save changes to '%s' (Y/N): ") % orig)
+        dlg.set_title(_("Sandbox Message"))
+        dlg.set_position(gtk.WIN_POS_MOUSE)
+        dlg.show_all()
+        rc = dlg.run()
+        dlg.destroy()
+        if rc == gtk.RESPONSE_YES:
+            copy = True
+    else:
+        try:
+            input = raw_input
+        except NameError:
+            pass
+        ans = input(_("Do you want to save changes to '%s' (y/N): ") % orig)
+        if(re.match(_("[yY]"), ans)):
+            copy = True
+    if(copy):
+        shutil.copy2(new, orig)
+
 
 def reserve(level):
     sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
     sock.bind("\0%s" % level)
     fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
 
-def get_range():
-       try:
-              level =selinux.getcon_raw()[1].split(":")[4]
-              lowc,highc = level.split(".")
-              low = int(lowc[1:])
-              high = int(highc[1:])+1
-              if high - low == 0:
-                     raise IndexError
 
-              return low,high
-       except IndexError:
-              raise ValueError(_("User account must be setup with an MCS Range"))
+def get_range():
+    try:
+        level = selinux.getcon_raw()[1].split(":")[4]
+        lowc, highc = level.split(".")
+        low = int(lowc[1:])
+        high = int(highc[1:]) + 1
+        if high - low == 0:
+            raise IndexError
+
+        return low, high
+    except IndexError:
+        raise ValueError(_("User account must be setup with an MCS Range"))
+
 
 def gen_mcs():
-       low, high = get_range()
+    low, high = get_range()
 
-       level = None
-       ctr = 0
-       total = high-low
-       total = (total * (total - 1))/2
-       while ctr < total:
-              ctr += 1
-              i1 = random.randrange(low, high)
-              i2 = random.randrange(low, high)
-              if i1 == i2:
-                     continue
-              if i1 > i2:
-                     tmp = i1
-                     i1 = i2
-                     i2 = tmp
-              level = "s0:c%d,c%d" % (i1, i2)
-              try:
-                     reserve(level)
-              except socket.error:
-                     continue
-              break
-       if level:
-              return level
-       raise ValueError(_("Failed to find any unused category sets.  Consider a larger MCS range for this user."))
+    level = None
+    ctr = 0
+    total = high - low
+    total = (total * (total - 1)) / 2
+    while ctr < total:
+        ctr += 1
+        i1 = random.randrange(low, high)
+        i2 = random.randrange(low, high)
+        if i1 == i2:
+            continue
+        if i1 > i2:
+            tmp = i1
+            i1 = i2
+            i2 = tmp
+        level = "s0:c%d,c%d" % (i1, i2)
+        try:
+            reserve(level)
+        except socket.error:
+            continue
+        break
+    if level:
+        return level
+    raise ValueError(_("Failed to find any unused category sets.  Consider a larger MCS range for this user."))
 
 
 def fullpath(cmd):
-       for i in [ "/", "./", "../" ]:
-              if cmd.startswith(i):
-                     return cmd
-       for i in  os.environ["PATH"].split(':'):
-              f = "%s/%s" % (i, cmd)
-              if os.access(f, os.X_OK):
-                     return f
-       return cmd
+    for i in ["/", "./", "../"]:
+        if cmd.startswith(i):
+            return cmd
+    for i in os.environ["PATH"].split(':'):
+        f = "%s/%s" % (i, cmd)
+        if os.access(f, os.X_OK):
+            return f
+    return cmd
+
 
 class Sandbox:
     SYSLOG = "/var/log/messages"
@@ -184,77 +207,77 @@
         self.__tmpdir = None
 
     def __validate_mount(self):
-           if self.__options.level:
-                  if not self.__options.homedir or not self.__options.tmpdir:
-                         self.usage(_("Homedir and tempdir required for level mounts"))
+        if self.__options.level:
+            if not self.__options.homedir or not self.__options.tmpdir:
+                self.usage(_("Homedir and tempdir required for level mounts"))
 
-           if not os.path.exists(SEUNSHARE):
-                  raise ValueError(_("""
+        if not os.path.exists(SEUNSHARE):
+            raise ValueError(_("""
 %s is required for the action you want to perform.
 """) % SEUNSHARE)
 
     def __mount_callback(self, option, opt, value, parser):
-           self.__mount = True
+        self.__mount = True
 
     def __x_callback(self, option, opt, value, parser):
-           self.__mount = True
-           setattr(parser.values, option.dest, True)
-           if not os.path.exists(SEUNSHARE):
-                  raise ValueError(_("""
+        self.__mount = True
+        setattr(parser.values, option.dest, True)
+        if not os.path.exists(SEUNSHARE):
+            raise ValueError(_("""
 %s is required for the action you want to perform.
 """) % SEUNSHARE)
 
-           if not os.path.exists(SANDBOXSH):
-                  raise ValueError(_("""
+        if not os.path.exists(SANDBOXSH):
+            raise ValueError(_("""
 %s is required for the action you want to perform.
 """) % SANDBOXSH)
 
     def __validdir(self, option, opt, value, parser):
-           if not os.path.isdir(value):
-                  raise IOError("Directory "+value+" not found")
-           setattr(parser.values, option.dest, value)
-           self.__mount = True
+        if not os.path.isdir(value):
+            raise IOError("Directory " + value + " not found")
+        setattr(parser.values, option.dest, value)
+        self.__mount = True
 
     def __include(self, option, opt, value, parser):
-           rp = os.path.realpath(os.path.expanduser(value))
-           if not os.path.exists(rp):
-                  raise IOError(value+" not found")
+        rp = os.path.realpath(os.path.expanduser(value))
+        if not os.path.exists(rp):
+            raise IOError(value + " not found")
 
-           if rp not in self.__init_files:
-                  self.__init_files.append(rp)
+        if rp not in self.__init_files:
+            self.__init_files.append(rp)
 
     def __includefile(self, option, opt, value, parser):
-           fd = open(value, "r")
-           for i in fd.readlines():
-                  try:
-                         self.__include(option, opt, i[:-1], parser)
-                  except IOError, e:
-                         sys.stderr.write(str(e))
-                  except TypeError, e:
-                         sys.stderr.write(str(e))
-           fd.close()
+        fd = open(value, "r")
+        for i in fd.readlines():
+            try:
+                self.__include(option, opt, i[:-1], parser)
+            except IOError as e:
+                sys.stderr.write(str(e))
+            except TypeError as e:
+                sys.stderr.write(str(e))
+        fd.close()
 
     def __copyfiles(self):
-           files = self.__init_files + self.__paths
-           homedir=pwd.getpwuid(os.getuid()).pw_dir
-           for f in files:
-                  copyfile(f, homedir, self.__homedir)
-                  copyfile(f, "/tmp", self.__tmpdir)
-                  copyfile(f, "/var/tmp", self.__tmpdir)
+        files = self.__init_files + self.__paths
+        homedir = pwd.getpwuid(os.getuid()).pw_dir
+        for f in files:
+            copyfile(f, homedir, self.__homedir)
+            copyfile(f, "/tmp", self.__tmpdir)
+            copyfile(f, "/var/tmp", self.__tmpdir)
 
-    def __setup_sandboxrc(self, wm = "/usr/bin/openbox"):
-           execfile =self.__homedir + "/.sandboxrc"
-           fd = open(execfile, "w+") 
-           if self.__options.session:
-                  fd.write("""#!/bin/sh
+    def __setup_sandboxrc(self, wm="/usr/bin/openbox"):
+        execfile = self.__homedir + "/.sandboxrc"
+        fd = open(execfile, "w+")
+        if self.__options.session:
+            fd.write("""#!/bin/sh
 #TITLE: /etc/gdm/Xsession
 /etc/gdm/Xsession
 """)
-           else:
-                  command = self.__paths[0] + " "
-                  for p in self.__paths[1:]:
-                         command += "'%s' " % p
-                  fd.write("""#! /bin/sh
+        else:
+            command = self.__paths[0] + " "
+            for p in self.__paths[1:]:
+                command += "'%s' " % p
+            fd.write("""#! /bin/sh
 #TITLE: %s
 /usr/bin/test -r ~/.xmodmap && /usr/bin/xmodmap ~/.xmodmap
 %s &
@@ -262,22 +285,22 @@
 dbus-launch --exit-with-session %s
 kill -TERM $WM_PID  2> /dev/null
 """ % (command, wm, command))
-           fd.close()
-           os.chmod(execfile, 0700)
+        fd.close()
+        os.chmod(execfile, 0o700)
 
-    def usage(self, message = ""):
-           error_exit("%s\n%s" % (self.__parser.usage, message))
+    def usage(self, message=""):
+        error_exit("%s\n%s" % (self.__parser.usage, message))
 
     def __parse_options(self):
         from optparse import OptionParser
         types = ""
         try:
-               types = _("""
+            types = _("""
 Policy defines the following types for use with the -t:
 \t%s
 """) % "\n\t".join(sepolicy.info(sepolicy.ATTRIBUTE, "sandbox_type")[0]['types'])
         except RuntimeError:
-               pass
+            pass
 
         usage = _("""
 sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [-W windowmanager ] [ -w windowsize ] [[-i file ] ...] [ -t type ] command
@@ -288,34 +311,34 @@
 
         parser = OptionParser(usage=usage)
         parser.disable_interspersed_args()
-        parser.add_option("-i", "--include", 
-                          action="callback", callback=self.__include, 
+        parser.add_option("-i", "--include",
+                          action="callback", callback=self.__include,
                           type="string",
                           help=_("include file in sandbox"))
-        parser.add_option("-I", "--includefile",  action="callback", callback=self.__includefile,
+        parser.add_option("-I", "--includefile", action="callback", callback=self.__includefile,
                           type="string",
                           help=_("read list of files to include in sandbox from INCLUDEFILE"))
         parser.add_option("-t", "--type", dest="setype", action="store", default=None,
                           help=_("run sandbox with SELinux type"))
-        parser.add_option("-M", "--mount", 
-                          action="callback", callback=self.__mount_callback, 
+        parser.add_option("-M", "--mount",
+                          action="callback", callback=self.__mount_callback,
                           help=_("mount new home and/or tmp directory"))
 
         parser.add_option("-d", "--dpi",
                           dest="dpi", action="store",
                           help=_("dots per inch for X display"))
 
-        parser.add_option("-S", "--session", action="store_true",  dest="session", 
-                          default=False,  help=_("run complete desktop session within sandbox"))
+        parser.add_option("-S", "--session", action="store_true", dest="session",
+                          default=False, help=_("run complete desktop session within sandbox"))
 
-        parser.add_option("-s", "--shred", action="store_true",  dest="shred", 
-                          default=False,  help=_("Shred content before tempory directories are removed"))
+        parser.add_option("-s", "--shred", action="store_true", dest="shred",
+                          default=False, help=_("Shred content before tempory directories are removed"))
 
-        parser.add_option("-X", dest="X_ind", 
-                          action="callback", callback=self.__x_callback, 
-                          default=False,  help=_("run X application within a sandbox"))
+        parser.add_option("-X", dest="X_ind",
+                          action="callback", callback=self.__x_callback,
+                          default=False, help=_("run X application within a sandbox"))
 
-        parser.add_option("-H", "--homedir", 
+        parser.add_option("-H", "--homedir",
                           action="callback", callback=self.__validdir,
                           type="string",
                           dest="homedir",
@@ -330,156 +353,157 @@
                           type="string", default=DEFAULT_WINDOWSIZE,
                           help="size of the sandbox window")
 
-        parser.add_option("-W", "--windowmanager", dest="wm",  
+        parser.add_option("-W", "--windowmanager", dest="wm",
                           type="string",
                           default="/usr/bin/openbox",
                           help=_("alternate window manager"))
 
-        parser.add_option("-l", "--level", dest="level", 
+        parser.add_option("-l", "--level", dest="level",
                           help=_("MCS/MLS level for the sandbox"))
 
         parser.add_option("-C", "--capabilities",
-                         action="store_true", dest="usecaps", default=False,
-                         help="Allow apps requiring capabilities to run within the sandbox.")
+                          action="store_true", dest="usecaps", default=False,
+                          help="Allow apps requiring capabilities to run within the sandbox.")
 
-        self.__parser=parser
+        self.__parser = parser
 
         self.__options, cmds = parser.parse_args()
 
         if self.__options.X_ind:
-               self.setype = DEFAULT_X_TYPE
+            self.setype = DEFAULT_X_TYPE
         else:
-               try:
-                      sepolicy.info(sepolicy.TYPE, "sandbox_t")
-               except RuntimeError:
-                      raise ValueError(_("Sandbox Policy is not currently installed.\nYou need to install the selinux-policy-sandbox package in order to run this command"))
-               
+            try:
+                sepolicy.info(sepolicy.TYPE, "sandbox_t")
+            except RuntimeError:
+                raise ValueError(_("Sandbox Policy is not currently installed.\nYou need to install the selinux-policy-sandbox package in order to run this command"))
+
         if self.__options.setype:
-               self.setype = self.__options.setype
+            self.setype = self.__options.setype
 
         if self.__mount:
-               self.__validate_mount()
+            self.__validate_mount()
 
         if self.__options.session:
-               if not self.__options.setype:
-                      self.setype = selinux.getcon()[1].split(":")[2]
-               if not self.__options.homedir or not self.__options.tmpdir:
-                      self.usage(_("You must specify a Homedir and tempdir when setting up a session sandbox"))
-               if len(cmds) > 0:
-                      self.usage(_("Commands are not allowed in a session sandbox"))
-               self.__options.X_ind = True
-               self.__homedir = self.__options.homedir
-               self.__tmpdir = self.__options.tmpdir
+            if not self.__options.setype:
+                self.setype = selinux.getcon()[1].split(":")[2]
+            if not self.__options.homedir or not self.__options.tmpdir:
+                self.usage(_("You must specify a Homedir and tempdir when setting up a session sandbox"))
+            if len(cmds) > 0:
+                self.usage(_("Commands are not allowed in a session sandbox"))
+            self.__options.X_ind = True
+            self.__homedir = self.__options.homedir
+            self.__tmpdir = self.__options.tmpdir
         else:
-               if self.__options.level:
-                      self.__homedir = self.__options.homedir
-                      self.__tmpdir = self.__options.tmpdir
+            if self.__options.level:
+                self.__homedir = self.__options.homedir
+                self.__tmpdir = self.__options.tmpdir
 
-               if len(cmds) == 0:
-                      self.usage(_("Command required"))
-               cmds[0] = fullpath(cmds[0])
-               if not os.access(cmds[0], os.X_OK):
-                      self.usage(_("%s is not an executable") % cmds[0]  )
-                      
-               self.__cmds = cmds
+            if len(cmds) == 0:
+                self.usage(_("Command required"))
+            cmds[0] = fullpath(cmds[0])
+            if not os.access(cmds[0], os.X_OK):
+                self.usage(_("%s is not an executable") % cmds[0])
+
+            self.__cmds = cmds
 
         for f in cmds:
-               rp = os.path.realpath(f)
-               if os.path.exists(rp):
-                      self.__paths.append(rp)
-               else:
-                      self.__paths.append(f)
-                  
+            rp = os.path.realpath(f)
+            if os.path.exists(rp):
+                self.__paths.append(rp)
+            else:
+                self.__paths.append(f)
+
     def __gen_context(self):
-           if self.__options.level:
-                  level = self.__options.level
-           else:
-                  level = gen_mcs()
+        if self.__options.level:
+            level = self.__options.level
+        else:
+            level = gen_mcs()
 
-           con = selinux.getcon()[1].split(":")
-           self.__execcon = "%s:%s:%s:%s" % (con[0], con[1], self.setype, level)
-           self.__filecon = "%s:object_r:sandbox_file_t:%s" % (con[0], level)
+        con = selinux.getcon()[1].split(":")
+        self.__execcon = "%s:%s:%s:%s" % (con[0], con[1], self.setype, level)
+        self.__filecon = "%s:object_r:sandbox_file_t:%s" % (con[0], level)
+
     def __setup_dir(self):
-           if self.__options.level or self.__options.session:
-                  return
+        if self.__options.level or self.__options.session:
+            return
 
-           if self.__options.homedir:
-                  selinux.chcon(self.__options.homedir, self.__filecon, recursive=True)
-                  self.__homedir = self.__options.homedir
-           else:
-                  selinux.setfscreatecon(self.__filecon)
-                  self.__homedir = mkdtemp(dir="/tmp", prefix=".sandbox_home_")
+        if self.__options.homedir:
+            selinux.chcon(self.__options.homedir, self.__filecon, recursive=True)
+            self.__homedir = self.__options.homedir
+        else:
+            selinux.setfscreatecon(self.__filecon)
+            self.__homedir = mkdtemp(dir="/tmp", prefix=".sandbox_home_")
 
-           if self.__options.tmpdir:
-                  selinux.chcon(self.__options.tmpdir, self.__filecon, recursive=True)
-                  self.__tmpdir = self.__options.tmpdir
-           else:
-                  selinux.setfscreatecon(self.__filecon)
-                  self.__tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_tmp_")
-           selinux.setfscreatecon(None)
-           self.__copyfiles()
+        if self.__options.tmpdir:
+            selinux.chcon(self.__options.tmpdir, self.__filecon, recursive=True)
+            self.__tmpdir = self.__options.tmpdir
+        else:
+            selinux.setfscreatecon(self.__filecon)
+            self.__tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_tmp_")
+        selinux.setfscreatecon(None)
+        self.__copyfiles()
 
     def __execute(self):
-           try:
-                  cmds = [ SEUNSHARE,  "-Z", self.__execcon ]
-                  if self.__options.usecaps:
-                         cmds.append('-C')
-                  if self.__mount:
-                         cmds +=  [ "-t", self.__tmpdir, "-h", self.__homedir ]
+        try:
+            cmds = [SEUNSHARE, "-Z", self.__execcon]
+            if self.__options.usecaps:
+                cmds.append('-C')
+            if self.__mount:
+                cmds += ["-t", self.__tmpdir, "-h", self.__homedir]
 
-                         if self.__options.X_ind:
-                                if self.__options.dpi:
-                                       dpi = self.__options.dpi
-                                else:
-                                       import gtk
-                                       dpi = str(gtk.settings_get_default().props.gtk_xft_dpi/1024)
+                if self.__options.X_ind:
+                    if self.__options.dpi:
+                        dpi = self.__options.dpi
+                    else:
+                        import gtk
+                        dpi = str(gtk.settings_get_default().props.gtk_xft_dpi / 1024)
 
-                                xmodmapfile = self.__homedir + "/.xmodmap"
-                                xd = open(xmodmapfile,"w")
-                                subprocess.Popen(["/usr/bin/xmodmap","-pke"],stdout=xd).wait()
-                                xd.close()
+                    xmodmapfile = self.__homedir + "/.xmodmap"
+                    xd = open(xmodmapfile, "w")
+                    subprocess.Popen(["/usr/bin/xmodmap", "-pke"], stdout=xd).wait()
+                    xd.close()
 
-                                self.__setup_sandboxrc(self.__options.wm)
+                    self.__setup_sandboxrc(self.__options.wm)
 
-                                cmds += [ "--", SANDBOXSH, self.__options.windowsize, dpi ]
-                         else:
-                                cmds += [ "--" ] + self.__paths
-                         return subprocess.Popen(cmds).wait()
+                    cmds += ["--", SANDBOXSH, self.__options.windowsize, dpi]
+                else:
+                    cmds += ["--"] + self.__paths
+                return subprocess.Popen(cmds).wait()
 
-                  selinux.setexeccon(self.__execcon)
-                  rc = subprocess.Popen(self.__cmds).wait()
-                  selinux.setexeccon(None)
-                  return rc
+            selinux.setexeccon(self.__execcon)
+            rc = subprocess.Popen(self.__cmds).wait()
+            selinux.setexeccon(None)
+            return rc
 
-           finally:
-                  for i in self.__paths:
-                         if i not in SAVE_FILES:
-                                continue
-                         (dest, mtime) = SAVE_FILES[i]
-                         if os.path.getmtime(dest) > mtime:
-                                savefile(dest, i, self.__options.X_ind)
+        finally:
+            for i in self.__paths:
+                if i not in SAVE_FILES:
+                    continue
+                (dest, mtime) = SAVE_FILES[i]
+                if os.path.getmtime(dest) > mtime:
+                    savefile(dest, i, self.__options.X_ind)
 
-                  if self.__homedir and not self.__options.homedir: 
-                         if self.__options.shred:
-                                self.shred(self.__homedir)
-                         shutil.rmtree(self.__homedir)
-                  if self.__tmpdir and not self.__options.tmpdir:
-                         if self.__options.shred:
-                                self.shred(self.__homedir)
-                         shutil.rmtree(self.__tmpdir)
+            if self.__homedir and not self.__options.homedir:
+                if self.__options.shred:
+                    self.shred(self.__homedir)
+                shutil.rmtree(self.__homedir)
+            if self.__tmpdir and not self.__options.tmpdir:
+                if self.__options.shred:
+                    self.shred(self.__homedir)
+                shutil.rmtree(self.__tmpdir)
 
     def shred(self, path):
         for root, dirs, files in os.walk(path):
             for f in files:
                 dest = root + "/" + f
-                subprocess.Popen(["/usr/bin/shred",dest]).wait()
+                subprocess.Popen(["/usr/bin/shred", dest]).wait()
 
     def main(self):
         try:
-               self.__parse_options()
-               self.__gen_context()
-               self.__setup_dir()
-               return self.__execute()
+            self.__parse_options()
+            self.__gen_context()
+            self.__setup_dir()
+            return self.__execute()
         except KeyboardInterrupt:
             sys.exit(0)
 
@@ -488,19 +512,19 @@
     setup_sighandlers()
     if selinux.is_selinux_enabled() != 1:
         error_exit("Requires an SELinux enabled system")
-    
+
     try:
-           sandbox = Sandbox()
-           rc = sandbox.main()
-    except OSError, error:
-           error_exit(error)
-    except ValueError, error:
-           error_exit(error.args[0])
-    except KeyError, error:
-           error_exit(_("Invalid value %s") % error.args[0])
-    except IOError, error:
-           error_exit(error)
+        sandbox = Sandbox()
+        rc = sandbox.main()
+    except OSError as error:
+        error_exit(error)
+    except ValueError as error:
+        error_exit(error.args[0])
+    except KeyError as error:
+        error_exit(_("Invalid value %s") % error.args[0])
+    except IOError as error:
+        error_exit(error)
     except KeyboardInterrupt:
-           rc = 0
-           
+        rc = 0
+
     sys.exit(rc)
diff --git a/policycoreutils/sandbox/start b/policycoreutils/sandbox/start
index 52950d7..fc406e1 100644
--- a/policycoreutils/sandbox/start
+++ b/policycoreutils/sandbox/start
@@ -1,9 +1,11 @@
 #! /usr/bin/python -Es
-import gtk, commands, sys
-rc = [-1,'']
+import gtk
+import subprocess
+import sys
+rc = [-1, '']
 try:
-    rc=commands.getstatusoutput(sys.argv[1])
+    rc = subprocess.getstatusoutput(sys.argv[1])
 except:
     pass
 if rc[0] == 0:
-    print rc[1]
+    print(rc[1])
diff --git a/policycoreutils/sandbox/test_sandbox.py b/policycoreutils/sandbox/test_sandbox.py
index b3b7f64..6f54d0c 100644
--- a/policycoreutils/sandbox/test_sandbox.py
+++ b/policycoreutils/sandbox/test_sandbox.py
@@ -1,29 +1,34 @@
-import unittest, os, shutil 
+import unittest
+import os
+import shutil
 from tempfile import mkdtemp
 from subprocess import Popen, PIPE
 
+
 class SandboxTests(unittest.TestCase):
+
     def assertDenied(self, err):
-        self.assert_('Permission denied' in err,
-                     '"Permission denied" not found in %r' % err)
+        self.assertTrue(b'Permission denied' in err,
+                        '"Permission denied" not found in %r' % err)
+
     def assertNotFound(self, err):
-        self.assert_('not found' in err,
-                     '"not found" not found in %r' % err)
+        self.assertTrue(b'not found' in err,
+                        '"not found" not found in %r' % err)
 
     def assertFailure(self, status):
-        self.assert_(status != 0,
-                     '"Succeeded when it should have failed')
+        self.assertTrue(status != 0,
+                        '"Succeeded when it should have failed')
 
     def assertSuccess(self, status, err):
-        self.assert_(status == 0,
-                     '"Sandbox should have succeeded for this test %r' %  err)
+        self.assertTrue(status == 0,
+                        '"Sandbox should have succeeded for this test %r' % err)
 
     def test_simple_success(self):
         "Verify that we can read file descriptors handed to sandbox"
-        p1 = Popen(['cat', '/etc/passwd'], stdout = PIPE)
-        p2 = Popen(['sandbox', 'grep', 'root'], stdin = p1.stdout, stdout=PIPE)
+        p1 = Popen(['cat', '/etc/passwd'], stdout=PIPE)
+        p2 = Popen(['sandbox', 'grep', 'root'], stdin=p1.stdout, stdout=PIPE)
         out, err = p2.communicate()
-        self.assert_('root' in out)
+        self.assertTrue(b'root' in out)
 
     def test_cant_kill(self):
         "Verify that we cannot send kill signal in the sandbox"
@@ -37,7 +42,7 @@
         p = Popen(['sandbox', 'ping', '-c 1 ', '127.0.0.1'], stdout=PIPE, stderr=PIPE)
         out, err = p.communicate()
         self.assertDenied(err)
-    
+
     def test_cant_mkdir(self):
         "Verify that we can't mkdir within the sandbox"
         p = Popen(['sandbox', 'mkdir', '~/test'], stdout=PIPE, stderr=PIPE)
@@ -55,25 +60,25 @@
         p = Popen(['sandbox', 'mail'], stdout=PIPE, stderr=PIPE)
         out, err = p.communicate()
         self.assertDenied(err)
-    
+
     def test_cant_sudo(self):
         "Verify that we can't run sudo within the sandbox"
         p = Popen(['sandbox', 'sudo'], stdout=PIPE, stderr=PIPE)
         out, err = p.communicate()
         self.assertFailure(p.returncode)
-    
+
     def test_mount(self):
         "Verify that we mount a file system"
         p = Popen(['sandbox', '-M', 'id'], stdout=PIPE, stderr=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
-    
+
     def test_set_level(self):
         "Verify that we set level a file system"
         p = Popen(['sandbox', '-l', 's0', 'id'], stdout=PIPE, stderr=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
-    
+
     def test_homedir(self):
         "Verify that we set homedir a file system"
         homedir = mkdtemp(dir=".", prefix=".sandbox_test")
@@ -81,7 +86,7 @@
         out, err = p.communicate()
         shutil.rmtree(homedir)
         self.assertSuccess(p.returncode, err)
-    
+
     def test_tmpdir(self):
         "Verify that we set tmpdir a file system"
         tmpdir = mkdtemp(dir="/tmp", prefix=".sandbox_test")
@@ -89,10 +94,10 @@
         out, err = p.communicate()
         shutil.rmtree(tmpdir)
         self.assertSuccess(p.returncode, err)
-    
+
 if __name__ == "__main__":
     import selinux
     if selinux.security_getenforce() == 1:
         unittest.main()
     else:
-        print "SELinux must be in enforcing mode for this test"
+        print("SELinux must be in enforcing mode for this test")
diff --git a/policycoreutils/scripts/chcat b/policycoreutils/scripts/chcat
index 9efcb22..ec527e5 100755
--- a/policycoreutils/scripts/chcat
+++ b/policycoreutils/scripts/chcat
@@ -1,5 +1,5 @@
 #! /usr/bin/python -Es
-# Copyright (C) 2005 Red Hat 
+# Copyright (C) 2005 Red Hat
 # see file 'COPYING' for use and warranty information
 #
 #    chcat is a script that allows you modify the Security label on a file
@@ -18,19 +18,30 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #                                        02111-1307  USA
 #
-#  
-import commands, sys, os, pwd, string, getopt, selinux
+#
+import subprocess
+import sys
+import os
+import pwd
+import string
+import getopt
+import selinux
 import seobject
 import gettext
 
 try:
     gettext.install('policycoreutils')
 except IOError:
-       import __builtin__
-       __builtin__.__dict__['_'] = unicode
+    try:
+        import builtins
+        builtins.__dict__['_'] = str
+    except ImportError:
+        import __builtin__
+        __builtin__.__dict__['_'] = unicode
+
 
 def errorExit(error):
     sys.stderr.write("%s: " % sys.argv[0])
@@ -38,12 +49,14 @@
     sys.stderr.flush()
     sys.exit(1)
 
+
 def verify_users(users):
     for u in users:
         try:
             pwd.getpwnam(u)
         except KeyError:
-            error( "User %s does not exist" % u)
+            error("User %s does not exist" % u)
+
 
 def chcat_user_add(newcat, users):
     errors = 0
@@ -70,30 +83,30 @@
             if i not in cats:
                 cats.append(i)
 
-            
         if len(cats) > 0:
             new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
         else:
             new_serange = "%s-%s" % (serange[0], top[0])
-            
+
         if add_ind:
             cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
         else:
             cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
-        rc = commands.getstatusoutput(cmd)
+        rc = subprocess.getstatusoutput(cmd)
         if rc[0] != 0:
-            print rc[1]
+            print(rc[1])
             errors += 1
 
     return errors
-        
-def chcat_add(orig, newcat, objects,login_ind):
+
+
+def chcat_add(orig, newcat, objects, login_ind):
     if len(newcat) == 1:
         raise ValueError(_("Requires at least one category"))
 
     if login_ind == 1:
         return chcat_user_add(newcat, objects)
-    
+
     errors = 0
     sensitivity = newcat[0]
     cat = newcat[1]
@@ -101,13 +114,13 @@
     for f in objects:
         (rc, c) = selinux.getfilecon(f)
         con = c.split(":")[3:]
-        clist  =  translate(con)
+        clist = translate(con)
         if sensitivity != clist[0]:
-                print(_("Can not modify sensitivity levels using '+' on %s") % f)
+            print(_("Can not modify sensitivity levels using '+' on %s") % f)
 
         if len(clist) > 1:
             if cat in clist[1:]:
-                print _("%s is already in %s") % (f, orig)
+                print(_("%s is already in %s") % (f, orig))
                 continue
             clist.append(cat)
             cats = clist[1:]
@@ -118,12 +131,13 @@
         else:
             cat_string = cat
         cmd = 'chcon -l %s:%s %s' % (sensitivity, cat_string, f)
-        rc = commands.getstatusoutput(cmd)
+        rc = subprocess.getstatusoutput(cmd)
         if rc[0] != 0:
-            print rc[1]
+            print(rc[1])
             errors += 1
     return errors
 
+
 def chcat_user_remove(newcat, users):
     errors = 0
     logins = seobject.loginRecords()
@@ -153,17 +167,18 @@
             new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
         else:
             new_serange = "%s-%s" % (serange[0], top[0])
-            
+
         if add_ind:
             cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
         else:
             cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
-        rc = commands.getstatusoutput(cmd)
+        rc = subprocess.getstatusoutput(cmd)
         if rc[0] != 0:
-            print rc[1]
+            print(rc[1])
             errors += 1
     return errors
-        
+
+
 def chcat_remove(orig, newcat, objects, login_ind):
     if len(newcat) == 1:
         raise ValueError(_("Requires at least one category"))
@@ -180,12 +195,12 @@
         con = c.split(":")[3:]
         clist = translate(con)
         if sensitivity != clist[0]:
-                print(_("Can not modify sensitivity levels using '+' on %s") % f)
-                continue
-            
+            print(_("Can not modify sensitivity levels using '+' on %s") % f)
+            continue
+
         if len(clist) > 1:
             if cat not in clist[1:]:
-                print _("%s is not in %s") % (f, orig)
+                print(_("%s is not in %s") % (f, orig))
                 continue
             clist.remove(cat)
             if len(clist) > 1:
@@ -195,19 +210,20 @@
             else:
                 cat = ""
         else:
-                print _("%s is not in %s") % (f, orig)
-                continue
-        
-        if len(cat) == 0: 
+            print(_("%s is not in %s") % (f, orig))
+            continue
+
+        if len(cat) == 0:
             cmd = 'chcon -l %s %s' % (sensitivity, f)
         else:
-            cmd = 'chcon -l %s:%s %s' % (sensitivity,cat, f)
-        rc = commands.getstatusoutput(cmd)
+            cmd = 'chcon -l %s:%s %s' % (sensitivity, cat, f)
+        rc = subprocess.getstatusoutput(cmd)
         if rc[0] != 0:
-            print rc[1]
+            print(rc[1])
             errors += 1
     return errors
 
+
 def chcat_user_replace(newcat, users):
     errors = 0
     logins = seobject.loginRecords()
@@ -221,7 +237,7 @@
             add_ind = 1
             user = seusers["__default__"]
         serange = user[1].split("-")
-        new_serange = "%s-%s:%s" % (serange[0],newcat[0], string.join(newcat[1:], ","))
+        new_serange = "%s-%s:%s" % (serange[0], newcat[0], string.join(newcat[1:], ","))
         if new_serange[-1:] == ":":
             new_serange = new_serange[:-1]
 
@@ -229,12 +245,13 @@
             cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
         else:
             cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
-        rc = commands.getstatusoutput(cmd)
+        rc = subprocess.getstatusoutput(cmd)
         if rc[0] != 0:
-            print rc[1]
+            print(rc[1])
             errors += 1
     return errors
-    
+
+
 def chcat_replace(newcat, objects, login_ind):
     if login_ind == 1:
         return chcat_user_replace(newcat, objects)
@@ -247,22 +264,23 @@
         cmd = 'chcon -l %s:%s' % (sensitivity, newcat[1])
         for cat in newcat[2:]:
             cmd = '%s,%s' % (cmd, cat)
-        
+
     for f in objects:
         cmd = "%s %s" % (cmd, f)
 
-    rc = commands.getstatusoutput(cmd)
+    rc = subprocess.getstatusoutput(cmd)
     if rc[0] != 0:
-        print rc[1]
+        print(rc[1])
         errors += 1
 
     return errors
 
+
 def check_replace(cats):
     plus_ind = 0
     replace_ind = 0
     for c in cats:
-        if len(c) > 0 and ( c[0] == "+" or c[0] == "-" ):
+        if len(c) > 0 and (c[0] == "+" or c[0] == "-"):
             if replace_ind:
                 raise ValueError(_("Can not combine +/- with other types of categories"))
             plus_ind = 1
@@ -272,12 +290,14 @@
                 raise ValueError(_("Can not combine +/- with other types of categories"))
     return replace_ind
 
+
 def isSensitivity(sensitivity):
-    if sensitivity[0] == "s" and sensitivity[1:].isdigit() and int(sensitivity[1:]) in range(0,16):
+    if sensitivity[0] == "s" and sensitivity[1:].isdigit() and int(sensitivity[1:]) in range(0, 16):
         return 1
     else:
         return 0
-    
+
+
 def expandCats(cats):
     newcats = []
     for c in cats:
@@ -295,6 +315,7 @@
         return cats
     return newcats
 
+
 def translate(cats):
     newcat = []
     if len(cats) == 0:
@@ -320,20 +341,22 @@
         for i in tlist[1:]:
             newcat.append(i)
     return newcat
-    
+
+
 def usage():
-	print _("Usage %s CATEGORY File ...") % sys.argv[0]
-	print _("Usage %s -l CATEGORY user ...") % sys.argv[0]
-	print _("Usage %s [[+|-]CATEGORY],...]q File ...") % sys.argv[0]
-	print _("Usage %s -l [[+|-]CATEGORY],...]q user ...") % sys.argv[0]
-	print _("Usage %s -d File ...") % sys.argv[0]
-	print _("Usage %s -l -d user ...") % sys.argv[0]
-	print _("Usage %s -L") % sys.argv[0]
-	print _("Usage %s -L -l user") % sys.argv[0]
-        print _("Use -- to end option list.  For example")
-        print _("chcat -- -CompanyConfidential /docs/businessplan.odt")
-        print _("chcat -l +CompanyConfidential juser")
-	sys.exit(1)
+    print(_("Usage %s CATEGORY File ...") % sys.argv[0])
+    print(_("Usage %s -l CATEGORY user ...") % sys.argv[0])
+    print(_("Usage %s [[+|-]CATEGORY],...]q File ...") % sys.argv[0])
+    print(_("Usage %s -l [[+|-]CATEGORY],...]q user ...") % sys.argv[0])
+    print(_("Usage %s -d File ...") % sys.argv[0])
+    print(_("Usage %s -l -d user ...") % sys.argv[0])
+    print(_("Usage %s -L") % sys.argv[0])
+    print(_("Usage %s -L -l user") % sys.argv[0])
+    print(_("Use -- to end option list.  For example"))
+    print(_("chcat -- -CompanyConfidential /docs/businessplan.odt"))
+    print(_("chcat -l +CompanyConfidential juser"))
+    sys.exit(1)
+
 
 def listcats():
     fd = open(selinux.selinux_translations_path())
@@ -342,10 +365,10 @@
             continue
         if l.find("=") != -1:
             rec = l.split("=")
-            print "%-30s %s" % tuple(rec)
+            print("%-30s %s" % tuple(rec))
     fd.close()
     return 0
-    
+
 
 def listusercats(users):
     if len(users) == 0:
@@ -356,21 +379,22 @@
         cats = seobject.translate(selinux.getseuserbyname(u)[2])
         cats = cats.split("-")
         if len(cats) > 1 and cats[1] != "s0":
-            print "%s: %s" % (u, cats[1])
+            print("%s: %s" % (u, cats[1]))
         else:
-            print "%s: %s" % (u, cats[0])
-            
+            print("%s: %s" % (u, cats[0]))
+
+
 def error(msg):
-    print "%s: %s" % (sys.argv[0], msg)
+    print("%s: %s" % (sys.argv[0], msg))
     sys.exit(1)
-    
+
 if __name__ == '__main__':
     if selinux.is_selinux_mls_enabled() != 1:
         error("Requires a mls enabled system")
-        
+
     if selinux.is_selinux_enabled() != 1:
         error("Requires an SELinux enabled system")
-        
+
     delete_ind = 0
     list_ind = 0
     login_ind = 0
@@ -382,7 +406,7 @@
                                      'help',
                                      'delete'])
 
-        for o,a in gopts:
+        for o, a in gopts:
             if o == "-h" or o == "--help":
                 usage()
             if o == "-d" or o == "--delete":
@@ -395,10 +419,10 @@
         if list_ind == 0 and len(cmds) < 1:
             usage()
 
-    except getopt.error, error:
+    except getopt.error as error:
         errorExit(_("Options Error %s ") % error.msg)
 
-    except ValueError, e:
+    except ValueError as e:
         usage()
 
     if delete_ind:
@@ -414,7 +438,7 @@
 
     if len(cmds) < 2:
         usage()
-    
+
     set_ind = 0
     cats = cmds[0].split(",")
     mod_ind = 0
@@ -428,17 +452,14 @@
                 l = []
                 l.append(c[1:])
                 if len(c) > 0 and c[0] == "+":
-                    errors += chcat_add(c[1:],translate(l), objects, login_ind)
+                    errors += chcat_add(c[1:], translate(l), objects, login_ind)
                     continue
                 if len(c) > 0 and c[0] == "-":
-                    errors += chcat_remove(c[1:],translate(l), objects, login_ind)
+                    errors += chcat_remove(c[1:], translate(l), objects, login_ind)
                     continue
-    except ValueError, e:
+    except ValueError as e:
         error(e)
-    except OSError, e:
+    except OSError as e:
         error(e)
-    
+
     sys.exit(errors)
-    
-
-
diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage
index dd63010..8097208 100644
--- a/policycoreutils/semanage/semanage
+++ b/policycoreutils/semanage/semanage
@@ -18,7 +18,7 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #                                        02111-1307  USA
 #
 #
@@ -27,59 +27,74 @@
 import seobject
 import sys
 import gettext
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 try:
-       gettext.install(PROGNAME,
-                       localedir="/usr/share/locale",
-                       unicode=True,
-                       codeset = 'utf-8')
+    kwargs = {}
+    if sys.version_info < (3,):
+        kwargs['unicode'] = True
+    gettext.install(PROGNAME,
+                    localedir="/usr/share/locale",
+                    codeset='utf-8',
+                    **kwargs)
 except IOError:
-       import __builtin__
-       __builtin__.__dict__['_'] = unicode
+    try:
+        import builtins
+        builtins.__dict__['_'] = str
+    except ImportError:
+        import __builtin__
+        __builtin__.__dict__['_'] = unicode
 
 # define custom usages for selected main actions
 usage_login = "semanage login [-h] [-n] [-N] [-s STORE] ["
-usage_login_dict = {' --add':('-s SEUSER','-r RANGE','LOGIN',),' --modify':('-s SEUSER','-r RANGE','LOGIN',),' --delete':('LOGIN',), ' --list':('-C',),' --extract':('',), ' --deleteall':('',)}
+usage_login_dict = {' --add': ('-s SEUSER', '-r RANGE', 'LOGIN',), ' --modify': ('-s SEUSER', '-r RANGE', 'LOGIN',), ' --delete': ('LOGIN',), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
 
 usage_fcontext = "semanage fcontext [-h] [-n] [-N] [-s STORE] ["
-usage_fcontext_dict = {' --add':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER', '|','-e EQUAL', ')','FILE_SPEC',')' ,),' --delete':('(','-t TYPE','-f FTYPE','|','-e EQUAL',')','FILE_SPEC', ')',),' --modify':('(','-t TYPE','-f FTYPE','-r RANGE','-s SEUSER','|','-e EQUAL',')','FILE_SPEC )',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_fcontext_dict = {' --add': ('(', '-t TYPE', '-f FTYPE', '-r RANGE', '-s SEUSER', '|', '-e EQUAL', ')', 'FILE_SPEC', ')',), ' --delete': ('(', '-t TYPE', '-f FTYPE', '|', '-e EQUAL', ')', 'FILE_SPEC', ')',), ' --modify': ('(', '-t TYPE', '-f FTYPE', '-r RANGE', '-s SEUSER', '|', '-e EQUAL', ')', 'FILE_SPEC )',), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
 
 usage_user = "semanage user [-h] [-n] [-N] [-s STORE] ["
-usage_user_dict = {' --add':('(','-L LEVEL','-R ROLES','-r RANGE','-s SEUSER','selinux_name'')'),' --delete':('selinux_name',),' --modify':('(','-L LEVEL','-R ROLES','-r RANGE','-s SEUSER','selinux_name',')'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_user_dict = {' --add': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'selinux_name'')'), ' --delete': ('selinux_name',), ' --modify': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'selinux_name', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
 
 usage_port = "semanage port [-h] [-n] [-N] [-s STORE] ["
-usage_port_dict = {' --add':('-t TYPE','-p PROTOCOL','-r RANGE','(','port_name','|','port_range',')'),' --modify':('-t TYPE','-p PROTOCOL','-r RANGE','(','port_name','|','port_range',')'), ' --delete':('-p PROTOCOL','(','port_name','|','port_range',')'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_port_dict = {' --add': ('-t TYPE', '-p PROTOCOL', '-r RANGE', '(', 'port_name', '|', 'port_range', ')'), ' --modify': ('-t TYPE', '-p PROTOCOL', '-r RANGE', '(', 'port_name', '|', 'port_range', ')'), ' --delete': ('-p PROTOCOL', '(', 'port_name', '|', 'port_range', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
 
 usage_node = "semanage node [-h] [-n] [-N] [-s STORE] ["
-usage_node_dict = {' --add':('-M NETMASK','-p PROTOCOL','-t TYPE','-r RANGE','node'),' --modify':('-M NETMASK','-p PROTOCOL','-t TYPE','-r RANGE','node'), ' --delete':('-M NETMASK','-p PROTOCOL','node'),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_node_dict = {' --add': ('-M NETMASK', '-p PROTOCOL', '-t TYPE', '-r RANGE', 'node'), ' --modify': ('-M NETMASK', '-p PROTOCOL', '-t TYPE', '-r RANGE', 'node'), ' --delete': ('-M NETMASK', '-p PROTOCOL', 'node'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
 
 usage_interface = "semanage interface [-h] [-n] [-N] [-s STORE] ["
-usage_interface_dict = {' --add':('-t TYPE','-r RANGE','interface'),' --modify':('-t TYPE','-r RANGE','interface'), ' --delete':('interface',),' --list':('-C',), ' --extract':('',), ' --deleteall':('',)}
+usage_interface_dict = {' --add': ('-t TYPE', '-r RANGE', 'interface'), ' --modify': ('-t TYPE', '-r RANGE', 'interface'), ' --delete': ('interface',), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)}
 
 usage_boolean = "semanage boolean [-h] [-n] [-N] [-s STORE] ["
-usage_boolean_dict = {' --modify':('(','--on','|','--off',')','boolean'), ' --list':('-C',), '  --extract':('',), ' --deleteall':('',)}
+usage_boolean_dict = {' --modify': ('(', '--on', '|', '--off', ')', 'boolean'), ' --list': ('-C',), '  --extract': ('',), ' --deleteall': ('',)}
 
 import sepolicy
+
+
 class CheckRole(argparse.Action):
+
     def __call__(self, parser, namespace, value, option_string=None):
         newval = getattr(namespace, self.dest)
         if not newval:
-               newval = []
+            newval = []
         roles = sepolicy.get_all_roles()
         for v in value.split():
-               if v not in roles:
-                      raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (v, ", ".join(roles)))
-               newval.append(v)
+            if v not in roles:
+                raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (v, ", ".join(roles)))
+            newval.append(v)
         setattr(namespace, self.dest, newval)
 
 store = ''
+
+
 class SetStore(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         global store
-        store=values
+        store = values
         setattr(namespace, self.dest, values)
 
+
 class seParser(argparse.ArgumentParser):
+
     def error(self, message):
         if len(sys.argv) == 2:
             self.print_help()
@@ -87,7 +102,9 @@
         self.print_usage()
         self.exit(2, ('%s: error: %s\n') % (self.prog, message))
 
+
 class SetExportFile(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         if values:
             if values is not "-":
@@ -98,74 +115,89 @@
                     sys.exit(1)
         setattr(namespace, self.dest, values)
 
+
 class SetImportFile(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         if values and values is not "-":
-               try:
-                      sys.stdin = open(values, 'r')
-               except IOError,e:
-                      sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
-                      sys.exit(1)
+            try:
+                sys.stdin = open(values, 'r')
+            except IOError as e:
+                sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
+                sys.exit(1)
         setattr(namespace, self.dest, values)
 
 # functions for OBJECT initialization
+
+
 def login_ini():
     OBJECT = seobject.loginRecords(store)
     return OBJECT
 
+
 def user_ini():
     OBJECT = seobject.seluserRecords(store)
     return OBJECT
 
+
 def port_ini():
     OBJECT = seobject.portRecords(store)
     return OBJECT
 
+
 def module_ini():
     OBJECT = seobject.moduleRecords(store)
     return OBJECT
 
+
 def interface_ini():
     OBJECT = seobject.interfaceRecords(store)
     return OBJECT
 
+
 def node_ini():
     OBJECT = seobject.nodeRecords(store)
     return OBJECT
 
+
 def fcontext_ini():
     OBJECT = seobject.fcontextRecords(store)
     return OBJECT
 
+
 def boolean_ini():
     OBJECT = seobject.booleanRecords(store)
     return OBJECT
 
+
 def permissive_ini():
     OBJECT = seobject.permissiveRecords(store)
     return OBJECT
 
+
 def dontaudit_ini():
     OBJECT = seobject.dontauditClass(store)
     return OBJECT
 
 # define dictonary for seobject OBEJCTS
-object_dict = {'login':login_ini, 'user':user_ini, 'port':port_ini, 'module':module_ini, 'interface':interface_ini, 'node':node_ini, 'fcontext':fcontext_ini, 'boolean':boolean_ini,'permissive':permissive_ini, 'dontaudit':dontaudit_ini}
+object_dict = {'login': login_ini, 'user': user_ini, 'port': port_ini, 'module': module_ini, 'interface': interface_ini, 'node': node_ini, 'fcontext': fcontext_ini, 'boolean': boolean_ini, 'permissive': permissive_ini, 'dontaudit': dontaudit_ini}
 
-def generate_custom_usage(usage_text,usage_dict):
+
+def generate_custom_usage(usage_text, usage_dict):
     # generate custom usage from given text and dictonary
     sorted_keys = []
     for i in usage_dict.keys():
         sorted_keys.append(i)
     sorted_keys.sort()
     for k in sorted_keys:
-        usage_text += "%s %s |" % (k,(" ".join(usage_dict[k])))
+        usage_text += "%s %s |" % (k, (" ".join(usage_dict[k])))
     usage_text = usage_text[:-1] + "]"
     usage_text = _(usage_text)
 
     return usage_text
 
-def handle_opts(args,dict,target_key):
+
+def handle_opts(args, dict, target_key):
     # handle conflict and required options for given dictonary
     # {action:[conflict_opts,require_opts]}
 
@@ -173,24 +205,25 @@
     for k in args.__dict__.keys():
         try:
             if k in dict[target_key][0] and args.__dict__[k]:
-                print("%s option can not be used with --%s" % (target_key,k))
+                print("%s option can not be used with --%s" % (target_key, k))
                 sys.exit(2)
         except KeyError:
             continue
 
     for k in args.__dict__.keys():
         try:
-         if k in dict[target_key][1] and not args.__dict__[k]:
-            print("%s option is needed for %s" % (k,target_key))
-            sys.exit(2)
+            if k in dict[target_key][1] and not args.__dict__[k]:
+                print("%s option is needed for %s" % (k, target_key))
+                sys.exit(2)
         except KeyError:
             continue
 
+
 def handleLogin(args):
     # {action:[conflict_opts,require_opts]}
-    login_args = {'list':[('login','seuser'),('')],'add':[('locallist'),('seuser','login')],'modify':[('locallist'),('login')], 'delete':[('locallist'),('login')],'extract':[('locallist','login','seuser'),('')],'deleteall':[('locallist'),('')]}
+    login_args = {'list': [('login', 'seuser'), ('')], 'add': [('locallist'), ('seuser', 'login')], 'modify': [('locallist'), ('login')], 'delete': [('locallist'), ('login')], 'extract': [('locallist', 'login', 'seuser'), ('')], 'deleteall': [('locallist'), ('')]}
 
-    handle_opts(args,login_args,args.action)
+    handle_opts(args, login_args, args.action)
 
     OBJECT = object_dict['login']()
     OBJECT.set_reload(args.noreload)
@@ -207,62 +240,82 @@
         OBJECT.deleteall()
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "login %s" % (str(i))
+            print("login %s" % (str(i)))
+
 
 def parser_add_store(parser, name):
     parser.add_argument('-S', '--store', action=SetStore, help=_("Select an alternate SELinux Policy Store to manage"))
 
+
 def parser_add_priority(parser, name):
     parser.add_argument('-P', '--priority', type=int, default=400, help=_("Select a priority for module operations"))
 
+
 def parser_add_noheading(parser, name):
-    parser.add_argument('-n', '--noheading', action='store_false', default=True, help=_("Do not print heading when listing %s object types") % name  )
+    parser.add_argument('-n', '--noheading', action='store_false', default=True, help=_("Do not print heading when listing %s object types") % name)
+
 
 def parser_add_noreload(parser, name):
     parser.add_argument('-N', '--noreload', action='store_false', default=True, help=_('Do not reload policy after commit'))
 
+
 def parser_add_locallist(parser, name):
-    parser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List %s local customizations") % name  )
+    parser.add_argument('-C', '--locallist', action='store_true', default=False, help=_("List %s local customizations") % name)
+
 
 def parser_add_add(parser, name):
-    parser.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_("Add a record of the %s object type") % name  )
+    parser.add_argument('-a', '--add', dest='action', action='store_const', const='add', help=_("Add a record of the %s object type") % name)
+
 
 def parser_add_type(parser, name):
     parser.add_argument('-t', '--type', help=_('SELinux Type for the object'))
+
+
 def parser_add_level(parser, name):
     parser.add_argument('-L', '--level', default='s0', help=_('Default SELinux Level for SELinux user, s0 Default. (MLS/MCS Systems only)'))
+
+
 def parser_add_range(parser, name):
     parser.add_argument('-r', '--range', default="s0",
-                             help=_('''
+                        help=_('''
 MLS/MCS Security Range (MLS/MCS Systems only)
 SELinux Range  for SELinux login mapping
 defaults to the SELinux user record range.
 SELinux Range for SELinux user defaults to s0.
 '''))
+
+
 def parser_add_proto(parser, name):
     parser.add_argument('-p', '--proto', help=_('''
     Protocol  for  the specified port (tcp|udp) or internet protocol
     version for the specified node (ipv4|ipv6).
 '''))
 
+
 def parser_add_modify(parser, name):
-    parser.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_("Modify a record of the %s object type") % name  )
+    parser.add_argument('-m', '--modify', dest='action', action='store_const', const='modify', help=_("Modify a record of the %s object type") % name)
+
 
 def parser_add_list(parser, name):
-    parser.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_("List records of the %s object type") % name  )
+    parser.add_argument('-l', '--list', dest='action', action='store_const', const='list', help=_("List records of the %s object type") % name)
+
 
 def parser_add_delete(parser, name):
-    parser.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_("Delete a record of the %s object type") % name  )
+    parser.add_argument('-d', '--delete', dest='action', action='store_const', const='delete', help=_("Delete a record of the %s object type") % name)
+
 
 def parser_add_extract(parser, name):
     parser.add_argument('-E', '--extract', dest='action', action='store_const', const='extract', help=_("Extract customizable commands, for use within a transaction"))
 
+
 def parser_add_deleteall(parser, name):
-    parser.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all %s objects local customizations') % name )
+    parser.add_argument('-D', '--deleteall', dest='action', action='store_const', const='deleteall', help=_('Remove all %s objects local customizations') % name)
+
 
 def parser_add_seuser(parser, name):
     parser.add_argument('-s', '--seuser', default="", help=_("SELinux user name"))
 
+
 def setupLoginParser(subparsers):
     generated_usage = generate_custom_usage(usage_login, usage_login_dict)
     loginParser = subparsers.add_parser('login', usage=generated_usage, help=_("Manage login mappings between linux users and SELinux confined users"))
@@ -286,13 +339,14 @@
 
     loginParser.set_defaults(func=handleLogin)
 
+
 def handleFcontext(args):
-    fcontext_args = {'list':[('equal','ftype','seuser','type'),('')],'add':[('locallist'),('type','file_spec')],'modify':[('locallist'),('type','file_spec')], 'delete':[('locallist'), ('file_spec')],'extract':[('locallist','equal','ftype','seuser','type'),('')],'deleteall':[('locallist'),('')]}
+    fcontext_args = {'list': [('equal', 'ftype', 'seuser', 'type'), ('')], 'add': [('locallist'), ('type', 'file_spec')], 'modify': [('locallist'), ('type', 'file_spec')], 'delete': [('locallist'), ('file_spec')], 'extract': [('locallist', 'equal', 'ftype', 'seuser', 'type'), ('')], 'deleteall': [('locallist'), ('')]}
     # we can not use mutually for equal because we can define some actions together with equal
-    fcontext_equal_args = {'equal':[('list','locallist','type','ftype','seuser','deleteall','extract'),()]}
+    fcontext_equal_args = {'equal': [('list', 'locallist', 'type', 'ftype', 'seuser', 'deleteall', 'extract'), ()]}
 
     if args.action is None:
-        print("usage: "+"%s" % generate_custom_usage(usage_fcontext, usage_fcontext_dict))
+        print("usage: " + "%s" % generate_custom_usage(usage_fcontext, usage_fcontext_dict))
         sys.exit(2)
     elif args.action and args.equal:
         handle_opts(args, fcontext_equal_args, "equal")
@@ -316,14 +370,15 @@
         if args.equal:
             OBJECT.delete(args.file_spec, args.equal)
         else:
-            OBJECT.delete(args.file_spec,args.ftype)
+            OBJECT.delete(args.file_spec, args.ftype)
     if args.action is "list":
         OBJECT.list(args.noheading, args.locallist)
     if args.action is "deleteall":
         OBJECT.deleteall()
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "fcontext %s" % str(i)
+            print("fcontext %s" % str(i))
+
 
 def setupFcontextParser(subparsers):
     ftype_help = '''
@@ -336,7 +391,7 @@
 If you do not specify a file type, the file type will default to "all files".
 '''
     generate_usage = generate_custom_usage(usage_fcontext, usage_fcontext_dict)
-    fcontextParser = subparsers.add_parser('fcontext',usage=generate_usage, help=_("Manage file context mapping definitions"))
+    fcontextParser = subparsers.add_parser('fcontext', usage=generate_usage, help=_("Manage file context mapping definitions"))
     parser_add_locallist(fcontextParser, "fcontext")
     parser_add_noheading(fcontextParser, "fcontext")
     parser_add_noreload(fcontextParser, "fcontext")
@@ -354,25 +409,26 @@
                                                                   label.  This is used with fcontext. Requires source  and  target
                                                                   path  arguments.  The context labeling for the target subtree is
                                                                   made equivalent to that defined for the source.'''))
-    fcontextParser.add_argument('-f', '--ftype', default="", choices=["a","f","d","c","b","s","l","p"], help=_(ftype_help))
+    fcontextParser.add_argument('-f', '--ftype', default="", choices=["a", "f", "d", "c", "b", "s", "l", "p"], help=_(ftype_help))
     parser_add_seuser(fcontextParser, "fcontext")
     parser_add_type(fcontextParser, "fcontext")
     parser_add_range(fcontextParser, "fcontext")
     fcontextParser.add_argument('file_spec', nargs='?', default=None, help=_('file_spec'))
     fcontextParser.set_defaults(func=handleFcontext)
 
-def handleUser(args):
-    user_args = {'list':[('selinux_name','seuser','roles'),('')],'add':[('locallist'),('roles','selinux_name')],'modify':[('locallist'),('selinux_name')], 'delete':[('locallist'),('selinux_name')],'extract':[('locallist','selinux_name','seuser','role'),('')],'deleteall':[('locallist'),('')]}
 
-    handle_opts(args,user_args,args.action)
+def handleUser(args):
+    user_args = {'list': [('selinux_name', 'seuser', 'roles'), ('')], 'add': [('locallist'), ('roles', 'selinux_name')], 'modify': [('locallist'), ('selinux_name')], 'delete': [('locallist'), ('selinux_name')], 'extract': [('locallist', 'selinux_name', 'seuser', 'role'), ('')], 'deleteall': [('locallist'), ('')]}
+
+    handle_opts(args, user_args, args.action)
 
     OBJECT = object_dict['user']()
     OBJECT.set_reload(args.noreload)
 
     if args.action is "add":
-        OBJECT.add(args.selinux_name, args.roles,  args.level, args.range, args.prefix)
+        OBJECT.add(args.selinux_name, args.roles, args.level, args.range, args.prefix)
     if args.action is "modify":
-        OBJECT.modify(args.selinux_name, args.roles,  args.level, args.range, args.prefix)
+        OBJECT.modify(args.selinux_name, args.roles, args.level, args.range, args.prefix)
     if args.action is "delete":
         OBJECT.delete(args.selinux_name)
     if args.action is "list":
@@ -381,11 +437,12 @@
         OBJECT.deleteall()
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "user %s" % str(i)
+            print("user %s" % str(i))
+
 
 def setupUserParser(subparsers):
     generated_usage = generate_custom_usage(usage_user, usage_user_dict)
-    userParser = subparsers.add_parser('user', usage=generated_usage,help=_('Manage SELinux confined users (Roles and levels for an SELinux user)'))
+    userParser = subparsers.add_parser('user', usage=generated_usage, help=_('Manage SELinux confined users (Roles and levels for an SELinux user)'))
     parser_add_locallist(userParser, "user")
     parser_add_noheading(userParser, "user")
     parser_add_noreload(userParser, "user")
@@ -406,14 +463,15 @@
                             help=_('''
 SELinux Roles.  You must enclose multiple roles within quotes,                  separate by spaces. Or specify -R multiple times.
 '''))
-    userParser.add_argument('-P', '--prefix', default="user",  help=argparse.SUPPRESS)
+    userParser.add_argument('-P', '--prefix', default="user", help=argparse.SUPPRESS)
     userParser.add_argument('selinux_name', nargs='?', default=None, help=_('selinux_name'))
     userParser.set_defaults(func=handleUser)
 
-def handlePort(args):
-    port_args = {'list':[('port','type','proto'),('')],'add':[('locallist'),('type','port','proto')],'modify':[('localist'),('port','proto')], 'delete':[('locallist'),('port','proto')],'extract':[('locallist','port','type','proto'),('')],'deleteall':[('locallist'),('')]}
 
-    handle_opts(args,port_args,args.action)
+def handlePort(args):
+    port_args = {'list': [('port', 'type', 'proto'), ('')], 'add': [('locallist'), ('type', 'port', 'proto')], 'modify': [('localist'), ('port', 'proto')], 'delete': [('locallist'), ('port', 'proto')], 'extract': [('locallist', 'port', 'type', 'proto'), ('')], 'deleteall': [('locallist'), ('')]}
+
+    handle_opts(args, port_args, args.action)
 
     OBJECT = object_dict['port']()
     OBJECT.set_reload(args.noreload)
@@ -430,7 +488,8 @@
         OBJECT.deleteall()
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "port %s" % str(i)
+            print("port %s" % str(i))
+
 
 def setupPortParser(subparsers):
     generated_usage = generate_custom_usage(usage_port, usage_port_dict)
@@ -453,10 +512,11 @@
     portParser.add_argument('port', nargs='?', default=None, help=_('port | port_range'))
     portParser.set_defaults(func=handlePort)
 
-def handleInterface(args):
-    interface_args = {'list':[('interface'),('')],'add':[('locallist'),('type','interface')],'modify':[('locallist'),('type','interface')], 'delete':[('locallist'),('interface')],'extract':[('locallist','interface','type'),('')],'deleteall':[('locallist'),('')]}
 
-    handle_opts(args,interface_args,args.action)
+def handleInterface(args):
+    interface_args = {'list': [('interface'), ('')], 'add': [('locallist'), ('type', 'interface')], 'modify': [('locallist'), ('type', 'interface')], 'delete': [('locallist'), ('interface')], 'extract': [('locallist', 'interface', 'type'), ('')], 'deleteall': [('locallist'), ('')]}
+
+    handle_opts(args, interface_args, args.action)
 
     OBJECT = object_dict['interface']()
     OBJECT.set_reload(args.noreload)
@@ -473,7 +533,8 @@
         OBJECT.deleteall()
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "interface %s" % str(i)
+            print("interface %s" % str(i))
+
 
 def setupInterfaceParser(subparsers):
     generated_usage = generate_custom_usage(usage_interface, usage_interface_dict)
@@ -495,6 +556,7 @@
     interfaceParser.add_argument('interface', nargs='?', default=None, help=_('interface_spec'))
     interfaceParser.set_defaults(func=handleInterface)
 
+
 def handleModule(args):
     OBJECT = seobject.moduleRecords(store)
     OBJECT.set_reload(args.noreload)
@@ -512,7 +574,8 @@
         OBJECT.list(args.noheading, args.locallist)
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "module %s" % str(i)
+            print("module %s" % str(i))
+
 
 def setupModuleParser(subparsers):
     moduleParser = subparsers.add_parser('module', help=_('Manage SELinux policy modules'))
@@ -533,9 +596,10 @@
     moduleParser.add_argument('module_name', nargs='?', default=None, help=_('Name of the module to act on'))
     moduleParser.set_defaults(func=handleModule)
 
+
 def handleNode(args):
-    node_args = {'list':[('node','type','proto','netmask'),('')],'add':[('locallist'),('type','node','proto','netmask')],'modify':[('locallist'),('node','netmask','proto')], 'delete':[('locallist'),('node','netmask','prototype')],'extract':[('locallist','node','type','proto','netmask'),('')],'deleteall':[('locallist'),('')]}
-    handle_opts(args,node_args,args.action)
+    node_args = {'list': [('node', 'type', 'proto', 'netmask'), ('')], 'add': [('locallist'), ('type', 'node', 'proto', 'netmask')], 'modify': [('locallist'), ('node', 'netmask', 'proto')], 'delete': [('locallist'), ('node', 'netmask', 'prototype')], 'extract': [('locallist', 'node', 'type', 'proto', 'netmask'), ('')], 'deleteall': [('locallist'), ('')]}
+    handle_opts(args, node_args, args.action)
 
     OBJECT = object_dict['node']()
     OBJECT.set_reload(args.noreload)
@@ -552,7 +616,8 @@
         OBJECT.deleteall()
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "node %s" % str(i)
+            print("node %s" % str(i))
+
 
 def setupNodeParser(subparsers):
     generated_usage = generate_custom_usage(usage_node, usage_node_dict)
@@ -570,45 +635,47 @@
     parser_add_extract(node_action, "node")
     parser_add_deleteall(node_action, "node")
 
-    nodeParser.add_argument('-M', '--netmask',  help=_('Network Mask'))
+    nodeParser.add_argument('-M', '--netmask', help=_('Network Mask'))
     parser_add_type(nodeParser, "node")
     parser_add_range(nodeParser, "node")
     parser_add_proto(nodeParser, "node")
     nodeParser.add_argument('node', nargs='?', default=None, help=_('node'))
     nodeParser.set_defaults(func=handleNode)
 
+
 def handleBoolean(args):
-    boolean_args = {'list':[('state','boolean'),('')],'modify':[('localist'),('')], 'extract':[('locallist','state','boolean'),('')],'deleteall':[('locallist'),('')],'state':[('locallist','list','extract','deleteall'),('modify')]}
+    boolean_args = {'list': [('state', 'boolean'), ('')], 'modify': [('localist'), ('')], 'extract': [('locallist', 'state', 'boolean'), ('')], 'deleteall': [('locallist'), ('')], 'state': [('locallist', 'list', 'extract', 'deleteall'), ('modify')]}
     if args.action is None:
-        print("Usage: "+"%s" % generate_custom_usage(usage_boolean, usage_boolean_dict))
+        print("Usage: " + "%s" % generate_custom_usage(usage_boolean, usage_boolean_dict))
         sys.exit(2)
     # TODO: should be added to handle_opts logic
     elif args.action is "modify" and not args.boolean:
-        print "boolean name required "
+        print("boolean name required ")
         sys.exit(1)
     elif args.action is "modify" and args.boolean and not args.state:
-        print "state option is needed"
+        print("state option is needed")
         sys.exit(1)
     else:
-        handle_opts(args,boolean_args,args.action)
+        handle_opts(args, boolean_args, args.action)
 
     OBJECT = object_dict['boolean']()
     OBJECT.set_reload(args.noreload)
 
     if args.action is "modify":
         if args.boolean:
-             OBJECT.modify(args.boolean, args.state, False)
+            OBJECT.modify(args.boolean, args.state, False)
     if args.action is "list":
         OBJECT.list(args.noheading, args.locallist)
     if args.action is "deleteall":
         OBJECT.deleteall()
     if args.action is "extract":
         for i in OBJECT.customized():
-            print "boolean %s" % str(i)
+            print("boolean %s" % str(i))
+
 
 def setupBooleanParser(subparsers):
     generated_usage = generate_custom_usage(usage_boolean, usage_boolean_dict)
-    booleanParser = subparsers.add_parser('boolean',usage=generated_usage, help=_('Manage booleans to selectively enable functionality'))
+    booleanParser = subparsers.add_parser('boolean', usage=generated_usage, help=_('Manage booleans to selectively enable functionality'))
     parser_add_locallist(booleanParser, "boolean")
     parser_add_noheading(booleanParser, "boolean")
     parser_add_noreload(booleanParser, "boolean")
@@ -628,6 +695,7 @@
 
     booleanParser.set_defaults(func=handleBoolean)
 
+
 def handlePermissive(args):
     OBJECT = object_dict['permissive']()
     OBJECT.set_reload(args.noreload)
@@ -639,6 +707,7 @@
     if args.action is "delete":
         OBJECT.delete(args.type)
 
+
 def setupPermissiveParser(subparsers):
     permissiveParser = subparsers.add_parser('permissive', help=_('Manage process type enforcement mode'))
 
@@ -655,11 +724,13 @@
     permissiveParser.add_argument('type', nargs='?', default=None, help=_('type'))
     permissiveParser.set_defaults(func=handlePermissive)
 
+
 def handleDontaudit(args):
     OBJECT = object_dict['dontaudit']()
     OBJECT.set_reload(args.noreload)
     OBJECT.toggle(args.action)
 
+
 def setupDontauditParser(subparsers):
     dontauditParser = subparsers.add_parser('dontaudit', help=_('Disable/Enable dontaudit rules in policy'))
     parser_add_noreload(dontauditParser, "dontaudit")
@@ -667,17 +738,19 @@
     dontauditParser.add_argument('action', choices=["on", "off"])
     dontauditParser.set_defaults(func=handleDontaudit)
 
+
 def handleExport(args):
-    manageditems=[ "boolean", "login", "interface", "user", "port", "node", "fcontext", "module"]
+    manageditems = ["boolean", "login", "interface", "user", "port", "node", "fcontext", "module"]
     for i in manageditems:
-        print "%s -D" % i
+        print("%s -D" % i)
     for i in manageditems:
         OBJECT = object_dict[i]()
         for c in OBJECT.customized():
-            print "%s %s" % (i, str(c))
+            print("%s %s" % (i, str(c)))
 
     sys.exit(0)
 
+
 def setupExportParser(subparsers):
     exportParser = subparsers.add_parser('export', help=_('Output local customizations'))
     parser_add_store(exportParser, "export")
@@ -685,6 +758,8 @@
     exportParser.set_defaults(func=handleExport)
 
 import re
+
+
 def mkargv(line):
     dquote = "\""
     squote = "\'"
@@ -698,10 +773,10 @@
             i = i + 1
             continue
         if cnt == 1:
-            quote = [ l[i].strip(dquote) ]
+            quote = [l[i].strip(dquote)]
             i = i + 1
 
-            while i < len(l) and  dquote not in l[i]:
+            while i < len(l) and dquote not in l[i]:
                 quote.append(l[i])
                 i = i + 1
             quote.append(l[i].strip(dquote))
@@ -715,9 +790,9 @@
             i = i + 1
             continue
         if cnt == 1:
-            quote = [ l[i].strip(squote) ]
+            quote = [l[i].strip(squote)]
             i = i + 1
-            while i < len(l) and  squote not in l[i]:
+            while i < len(l) and squote not in l[i]:
                 quote.append(l[i])
                 i = i + 1
 
@@ -731,22 +806,23 @@
 
     return ret
 
+
 def handleImport(args):
     trans = seobject.semanageRecords(store)
     trans.start()
 
     for l in sys.stdin.readlines():
         if len(l.strip()) == 0:
-               continue
+            continue
 
         try:
             commandParser = createCommandParser()
             args = commandParser.parse_args(mkargv(l))
             args.func(args)
-        except ValueError,e:
+        except ValueError as e:
             sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
             sys.exit(1)
-        except IOError,e:
+        except IOError as e:
             sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
             sys.exit(1)
         except KeyboardInterrupt:
@@ -755,6 +831,7 @@
     trans.set_reload(args.noreload)
     trans.finish()
 
+
 def setupImportParser(subparsers):
     importParser = subparsers.add_parser('import', help=_('Output local customizations'))
     parser_add_noreload(importParser, "import")
@@ -762,10 +839,11 @@
     importParser.add_argument('-f', '--input_file', dest='input_file', action=SetImportFile, help=_('Input file'))
     importParser.set_defaults(func=handleImport)
 
+
 def createCommandParser():
     commandParser = seParser(prog='semanage',
-                                            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
-                                            description='''semanage is used to configure certain elements
+                             formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+                             description='''semanage is used to configure certain elements
                                                             of SELinux policy with-out requiring modification
                                                             to or recompilation from policy source.''')
 
@@ -786,9 +864,10 @@
 
     return commandParser
 
+
 def make_io_args(args):
     # import/export backward compability
-    args_origin = ["-S", "-o", "-i", "targeted", "minumum", "mls"]
+    args_origin = ["-S", "-o", "-i", "targeted", "minimum", "mls"]
     args_file = []
     args_ie = []
     args_subcommand = []
@@ -805,40 +884,42 @@
             continue
         args_ie.append(i)
 
-    return args_subcommand+args_ie+args_file
+    return args_subcommand + args_ie + args_file
+
 
 def make_args(sys_args):
     args = []
     if "-o" in sys_args[1:] or "-i" in sys_args[1:]:
-        args=make_io_args(sys_args[1:])
+        args = make_io_args(sys_args[1:])
     else:
-        args=sys_args[1:]
+        args = sys_args[1:]
 
     return args
 
+
 def do_parser():
     try:
         commandParser = createCommandParser()
         args = commandParser.parse_args(make_args(sys.argv))
         args.func(args)
         sys.exit(0)
-    except IOError,e:
+    except IOError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
         sys.exit(1)
     except KeyboardInterrupt:
         sys.exit(0)
-    except ValueError, e:
+    except ValueError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
         sys.exit(1)
-    except KeyError, e:
+    except KeyError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
         sys.exit(1)
-    except OSError, e:
+    except OSError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[1]))
         sys.exit(1)
-    except RuntimeError, e:
+    except RuntimeError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, e.args[0]))
         sys.exit(1)
 
 if __name__ == '__main__':
-       do_parser()
+    do_parser()
diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
index 568ebfd..d29dba5 100644
--- a/policycoreutils/semanage/seobject.py
+++ b/policycoreutils/semanage/seobject.py
@@ -16,13 +16,22 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #                                        02111-1307  USA
 #
-#  
+#
 
-import pwd, grp, string, selinux, tempfile, os, re, sys, stat, shutil
-from semanage import *;
+import pwd
+import grp
+import string
+import selinux
+import tempfile
+import os
+import re
+import sys
+import stat
+import shutil
+from semanage import *
 PROGNAME = "policycoreutils"
 import sepolicy
 from sepolicy import boolean_desc, boolean_category, gen_bool_dict
@@ -34,2183 +43,2213 @@
 gettext.textdomain(PROGNAME)
 
 import gettext
-translation=gettext.translation(PROGNAME, localedir = "/usr/share/locale", fallback=True)
-_=translation.ugettext
+translation = gettext.translation(PROGNAME, localedir="/usr/share/locale", fallback=True)
+_ = translation.ugettext
 
 import syslog
 
 file_types = {}
-file_types[""] = SEMANAGE_FCONTEXT_ALL;
-file_types["all files"] = SEMANAGE_FCONTEXT_ALL;
-file_types["a"] = SEMANAGE_FCONTEXT_ALL;
-file_types["regular file"] = SEMANAGE_FCONTEXT_REG;
-file_types["--"] = SEMANAGE_FCONTEXT_REG;
-file_types["f"] = SEMANAGE_FCONTEXT_REG;
-file_types["-d"] = SEMANAGE_FCONTEXT_DIR;
-file_types["directory"] = SEMANAGE_FCONTEXT_DIR;
-file_types["d"] = SEMANAGE_FCONTEXT_DIR;
-file_types["-c"] = SEMANAGE_FCONTEXT_CHAR;
-file_types["character device"] = SEMANAGE_FCONTEXT_CHAR;
-file_types["c"] = SEMANAGE_FCONTEXT_CHAR;
-file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK;
-file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK;
-file_types["b"] = SEMANAGE_FCONTEXT_BLOCK;
-file_types["-s"] = SEMANAGE_FCONTEXT_SOCK;
-file_types["socket"] = SEMANAGE_FCONTEXT_SOCK;
-file_types["s"] = SEMANAGE_FCONTEXT_SOCK;
-file_types["-l"] = SEMANAGE_FCONTEXT_LINK;
-file_types["l"] = SEMANAGE_FCONTEXT_LINK;
-file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK;
-file_types["p"] = SEMANAGE_FCONTEXT_PIPE;
-file_types["-p"] = SEMANAGE_FCONTEXT_PIPE;
-file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE;
+file_types[""] = SEMANAGE_FCONTEXT_ALL
+file_types["all files"] = SEMANAGE_FCONTEXT_ALL
+file_types["a"] = SEMANAGE_FCONTEXT_ALL
+file_types["regular file"] = SEMANAGE_FCONTEXT_REG
+file_types["--"] = SEMANAGE_FCONTEXT_REG
+file_types["f"] = SEMANAGE_FCONTEXT_REG
+file_types["-d"] = SEMANAGE_FCONTEXT_DIR
+file_types["directory"] = SEMANAGE_FCONTEXT_DIR
+file_types["d"] = SEMANAGE_FCONTEXT_DIR
+file_types["-c"] = SEMANAGE_FCONTEXT_CHAR
+file_types["character device"] = SEMANAGE_FCONTEXT_CHAR
+file_types["c"] = SEMANAGE_FCONTEXT_CHAR
+file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK
+file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK
+file_types["b"] = SEMANAGE_FCONTEXT_BLOCK
+file_types["-s"] = SEMANAGE_FCONTEXT_SOCK
+file_types["socket"] = SEMANAGE_FCONTEXT_SOCK
+file_types["s"] = SEMANAGE_FCONTEXT_SOCK
+file_types["-l"] = SEMANAGE_FCONTEXT_LINK
+file_types["l"] = SEMANAGE_FCONTEXT_LINK
+file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK
+file_types["p"] = SEMANAGE_FCONTEXT_PIPE
+file_types["-p"] = SEMANAGE_FCONTEXT_PIPE
+file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE
 
-file_type_str_to_option = { "all files": "a",
-                            "regular file":"f",
-                            "directory":"d",
-                            "character device":"c",
-                            "block device":"b",
-                            "socket file":"s",
-                            "symbolic link":"l",
-                            "named pipe":"p" }
+file_type_str_to_option = {"all files": "a",
+                           "regular file": "f",
+                           "directory": "d",
+                           "character device": "c",
+                           "block device": "b",
+                           "socket file": "s",
+                           "symbolic link": "l",
+                           "named pipe": "p"}
 try:
-	import audit
-	class logger:
-		def __init__(self):
-			self.audit_fd = audit.audit_open()
-			self.log_list = []
-		def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
-			
-			sep = "-"
-			if sename != oldsename:
-				msg += sep + "sename"; sep = ","
-			if serole != oldserole:
-				msg += sep + "role"; sep = ","
-			if serange != oldserange:
-				msg += sep + "range"; sep = ","
+    import audit
 
-			self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+    class logger:
 
-		def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
-			self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+        def __init__(self):
+            self.audit_fd = audit.audit_open()
+            self.log_list = []
 
-		def commit(self,success):
-			for l in self.log_list:
-				audit.audit_log_semanage_message(*(l + [success]))
-			self.log_list = []
+        def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+
+            sep = "-"
+            if sename != oldsename:
+                msg += sep + "sename"
+                sep = ","
+            if serole != oldserole:
+                msg += sep + "role"
+                sep = ","
+            if serange != oldserange:
+                msg += sep + "range"
+                sep = ","
+
+            self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+
+        def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+            self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+
+        def commit(self, success):
+            for l in self.log_list:
+                audit.audit_log_semanage_message(*(l + [success]))
+            self.log_list = []
 except:
-	class logger:
-		def __init__(self):
-			self.log_list=[]
+    class logger:
 
-		def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
-			message = " %s name=%s" % (msg, name)
-			if sename != "":
-				message += " sename=" + sename
-			if oldsename != "":
-				message += " oldsename=" + oldsename
-			if serole != "":
-				message += " role=" + serole
-			if oldserole != "":
-				message += " old_role=" + oldserole
-			if serange != "" and serange != None:
-				message += " MLSRange=" + serange
-			if oldserange != "" and oldserange != None:
-				message += " old_MLSRange=" + oldserange
-			self.log_list.append(message)
+        def __init__(self):
+            self.log_list = []
 
-		def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
-			self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
+        def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+            message = " %s name=%s" % (msg, name)
+            if sename != "":
+                message += " sename=" + sename
+            if oldsename != "":
+                message += " oldsename=" + oldsename
+            if serole != "":
+                message += " role=" + serole
+            if oldserole != "":
+                message += " old_role=" + oldserole
+            if serange != "" and serange != None:
+                message += " MLSRange=" + serange
+            if oldserange != "" and oldserange != None:
+                message += " old_MLSRange=" + oldserange
+            self.log_list.append(message)
 
-		def commit(self,success):
-			if success == 1:
-				message = "Successful: "
-			else:
-				message = "Failed: "
-			for l in self.log_list:
-				syslog.syslog(syslog.LOG_INFO, message + l)
+        def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+            self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
+
+        def commit(self, success):
+            if success == 1:
+                message = "Successful: "
+            else:
+                message = "Failed: "
+            for l in self.log_list:
+                syslog.syslog(syslog.LOG_INFO, message + l)
+
 
 class nulllogger:
-	def log(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
-		pass
 
-	def log_remove(self, msg, name = "", sename = "", serole = "", serange = "", oldsename = "", oldserole = "", oldserange = ""):
-		pass
+    def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+        pass
 
-	def commit(self,success):
-		pass
+    def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
+        pass
+
+    def commit(self, success):
+        pass
+
 
 def validate_level(raw):
-	sensitivity = "s[0-9]*"
-	category = "c[0-9]*"
-	cat_range = category + "(\." + category +")?"
-	categories = cat_range + "(\," + cat_range + ")*"
-	reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
-	return re.search("^" + reg +"$", raw)
+    sensitivity = "s[0-9]*"
+    category = "c[0-9]*"
+    cat_range = category + "(\." + category + ")?"
+    categories = cat_range + "(\," + cat_range + ")*"
+    reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
+    return re.search("^" + reg + "$", raw)
 
-def translate(raw, prepend = 1):
-        filler = "a:b:c:"
-        if prepend == 1:
-		context = "%s%s" % (filler, raw)
-	else:
-		context = raw
-	(rc, trans) = selinux.selinux_raw_to_trans_context(context)
-	if rc != 0:
-		return raw
-	if prepend:
-		trans = trans[len(filler):]
-	if trans == "":
-		return raw
-	else:
-		return trans
-	
-def untranslate(trans, prepend = 1):
-        filler = "a:b:c:"
- 	if prepend == 1:
-		context = "%s%s" % (filler, trans)
-	else:
-		context = trans
 
-	(rc, raw) = selinux.selinux_trans_to_raw_context(context)
-	if rc != 0:
-		return trans
-	if prepend:
-		raw = raw[len(filler):]
-	if raw == "":
-		return trans
-	else:
-		return raw
+def translate(raw, prepend=1):
+    filler = "a:b:c:"
+    if prepend == 1:
+        context = "%s%s" % (filler, raw)
+    else:
+        context = raw
+    (rc, trans) = selinux.selinux_raw_to_trans_context(context)
+    if rc != 0:
+        return raw
+    if prepend:
+        trans = trans[len(filler):]
+    if trans == "":
+        return raw
+    else:
+        return trans
+
+
+def untranslate(trans, prepend=1):
+    filler = "a:b:c:"
+    if prepend == 1:
+        context = "%s%s" % (filler, trans)
+    else:
+        context = trans
+
+    (rc, raw) = selinux.selinux_trans_to_raw_context(context)
+    if rc != 0:
+        return trans
+    if prepend:
+        raw = raw[len(filler):]
+    if raw == "":
+        return trans
+    else:
+        return raw
+
 
 class semanageRecords:
-        transaction = False
-        handle = None
-        store = None
-        def __init__(self, store):
-               global handle
-	       self.load = True
-               self.sh = self.get_handle(store)
+    transaction = False
+    handle = None
+    store = None
 
-	       rc, localstore = selinux.selinux_getpolicytype()
-	       if store == "" or store == localstore:
-		       self.mylog = logger()	
-	       else:
-		       self.mylog = nulllogger()	
+    def __init__(self, store):
+        global handle
+        self.load = True
+        self.sh = self.get_handle(store)
 
-	def set_reload(self, load):
-	       self.load = load
+        rc, localstore = selinux.selinux_getpolicytype()
+        if store == "" or store == localstore:
+            self.mylog = logger()
+        else:
+            self.mylog = nulllogger()
 
-        def get_handle(self, store):
-		global is_mls_enabled
+    def set_reload(self, load):
+        self.load = load
 
-		if semanageRecords.handle:
-			return semanageRecords.handle
+    def get_handle(self, store):
+        global is_mls_enabled
 
-		handle = semanage_handle_create()
-		if not handle:
-			raise ValueError(_("Could not create semanage handle"))
+        if semanageRecords.handle:
+            return semanageRecords.handle
 
-		if not semanageRecords.transaction and store != "":
-			semanage_select_store(handle, store, SEMANAGE_CON_DIRECT);
-			semanageRecords.store = store
+        handle = semanage_handle_create()
+        if not handle:
+            raise ValueError(_("Could not create semanage handle"))
 
-		if not semanage_is_managed(handle):
-			semanage_handle_destroy(handle)
-			raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
+        if not semanageRecords.transaction and store != "":
+            semanage_select_store(handle, store, SEMANAGE_CON_DIRECT)
+            semanageRecords.store = store
 
-		rc = semanage_access_check(handle)
-		if rc < SEMANAGE_CAN_READ:
-			semanage_handle_destroy(handle)
-			raise ValueError(_("Cannot read policy store."))
+        if not semanage_is_managed(handle):
+            semanage_handle_destroy(handle)
+            raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
 
-		rc = semanage_connect(handle)
-		if rc < 0:
-			semanage_handle_destroy(handle)
-			raise ValueError(_("Could not establish semanage connection"))
+        rc = semanage_access_check(handle)
+        if rc < SEMANAGE_CAN_READ:
+            semanage_handle_destroy(handle)
+            raise ValueError(_("Cannot read policy store."))
 
-		is_mls_enabled = semanage_mls_enabled(handle)
-		if is_mls_enabled < 0:
-			semanage_handle_destroy(handle)
-			raise ValueError(_("Could not test MLS enabled status"))
+        rc = semanage_connect(handle)
+        if rc < 0:
+            semanage_handle_destroy(handle)
+            raise ValueError(_("Could not establish semanage connection"))
 
-		semanageRecords.handle = handle
-		return semanageRecords.handle
+        is_mls_enabled = semanage_mls_enabled(handle)
+        if is_mls_enabled < 0:
+            semanage_handle_destroy(handle)
+            raise ValueError(_("Could not test MLS enabled status"))
 
-        def deleteall(self):
-               raise ValueError(_("Not yet implemented"))
+        semanageRecords.handle = handle
+        return semanageRecords.handle
 
-        def start(self):
-               if semanageRecords.transaction:
-                      raise ValueError(_("Semanage transaction already in progress"))
-               self.begin()
-               semanageRecords.transaction = True
+    def deleteall(self):
+        raise ValueError(_("Not yet implemented"))
 
-        def begin(self):
-               if semanageRecords.transaction:
-                      return
-               rc = semanage_begin_transaction(self.sh)
-               if rc < 0:
-                      raise ValueError(_("Could not start semanage transaction"))
-        def customized(self):
-               raise ValueError(_("Not yet implemented"))
+    def start(self):
+        if semanageRecords.transaction:
+            raise ValueError(_("Semanage transaction already in progress"))
+        self.begin()
+        semanageRecords.transaction = True
 
-        def commit(self):
-		if semanageRecords.transaction:
-			return
+    def begin(self):
+        if semanageRecords.transaction:
+            return
+        rc = semanage_begin_transaction(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not start semanage transaction"))
 
-		semanage_set_reload(self.sh, self.load)
-		rc = semanage_commit(self.sh) 
-		if rc < 0:
-			self.mylog.commit(0)
-			raise ValueError(_("Could not commit semanage transaction"))
-		self.mylog.commit(1)
+    def customized(self):
+        raise ValueError(_("Not yet implemented"))
 
-        def finish(self):
-               if not semanageRecords.transaction:
-                      raise ValueError(_("Semanage transaction not in progress"))
-               semanageRecords.transaction = False
-               self.commit()
+    def commit(self):
+        if semanageRecords.transaction:
+            return
+
+        semanage_set_reload(self.sh, self.load)
+        rc = semanage_commit(self.sh)
+        if rc < 0:
+            self.mylog.commit(0)
+            raise ValueError(_("Could not commit semanage transaction"))
+        self.mylog.commit(1)
+
+    def finish(self):
+        if not semanageRecords.transaction:
+            raise ValueError(_("Semanage transaction not in progress"))
+        semanageRecords.transaction = False
+        self.commit()
+
 
 class moduleRecords(semanageRecords):
-	def __init__(self, store):
-	       semanageRecords.__init__(self, store)
 
-	def get_all(self):
-               l = []
-               (rc, mlist, number) = semanage_module_list_all(self.sh)
-               if rc < 0:
-                      raise ValueError(_("Could not list SELinux modules"))
+    def __init__(self, store):
+        semanageRecords.__init__(self, store)
 
-               for i in range(number):
-                      mod = semanage_module_list_nth(mlist, i)
+    def get_all(self):
+        l = []
+        (rc, mlist, number) = semanage_module_list_all(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list SELinux modules"))
 
-                      rc, name = semanage_module_info_get_name(self.sh, mod)
-                      if rc < 0:
-                          raise ValueError(_("Could not get module name"))
+        for i in range(number):
+            mod = semanage_module_list_nth(mlist, i)
 
-                      rc, enabled = semanage_module_info_get_enabled(self.sh, mod)
-                      if rc < 0:
-                          raise ValueError(_("Could not get module enabled"))
+            rc, name = semanage_module_info_get_name(self.sh, mod)
+            if rc < 0:
+                raise ValueError(_("Could not get module name"))
 
-                      rc, priority = semanage_module_info_get_priority(self.sh, mod)
-                      if rc < 0:
-                          raise ValueError(_("Could not get module priority"))
+            rc, enabled = semanage_module_info_get_enabled(self.sh, mod)
+            if rc < 0:
+                raise ValueError(_("Could not get module enabled"))
 
-                      rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod)
-                      if rc < 0:
-                          raise ValueError(_("Could not get module lang_ext"))
+            rc, priority = semanage_module_info_get_priority(self.sh, mod)
+            if rc < 0:
+                raise ValueError(_("Could not get module priority"))
 
-                      l.append((name, enabled, priority, lang_ext))
+            rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod)
+            if rc < 0:
+                raise ValueError(_("Could not get module lang_ext"))
 
-               # sort the list so they are in name order, but with higher priorities coming first
-               l.sort(key = lambda t: t[3], reverse=True)
-               l.sort(key = lambda t: t[0])
-               return l
+            l.append((name, enabled, priority, lang_ext))
 
-        def customized(self):
-		all = self.get_all()
-		if len(all) == 0:
-			return
-                return map(lambda x: "-d %s" % x[0], filter(lambda t: t[1] == 0, all))
+        # sort the list so they are in name order, but with higher priorities coming first
+        l.sort(key=lambda t: t[3], reverse=True)
+        l.sort(key=lambda t: t[0])
+        return l
 
-	def list(self, heading = 1, locallist = 0):
-		all = self.get_all()
-		if len(all) == 0:
-			return 
+    def customized(self):
+        all = self.get_all()
+        if len(all) == 0:
+            return
+        return map(lambda x: "-d %s" % x[0], filter(lambda t: t[1] == 0, all))
 
-		if heading:
-			print "\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language"))
-                for t in all:
-                       if t[1] == 0:
-                              disabled = _("Disabled")
-                       else:
-                              if locallist:
-                                      continue
-                              disabled = ""
-                       print "%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)
+    def list(self, heading=1, locallist=0):
+        all = self.get_all()
+        if len(all) == 0:
+            return
 
-	def add(self, file, priority):
-               if not os.path.exists(file):
-                       raise ValueError(_("Module does not exists %s ") % file)
+        if heading:
+            print "\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language"))
+        for t in all:
+            if t[1] == 0:
+                disabled = _("Disabled")
+            else:
+                if locallist:
+                    continue
+                disabled = ""
+            print "%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)
 
-               rc = semanage_set_default_priority(self.sh, priority)
-               if rc < 0:
-                       raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
+    def add(self, file, priority):
+        if not os.path.exists(file):
+            raise ValueError(_("Module does not exists %s ") % file)
 
-               rc = semanage_module_install_file(self.sh, file);
-               if rc >= 0:
-                      self.commit()
+        rc = semanage_set_default_priority(self.sh, priority)
+        if rc < 0:
+            raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
 
-	def set_enabled(self, module, enable):
-               for m in module.split():
-                      rc, key = semanage_module_key_create(self.sh)
-                      if rc < 0:
-                              raise ValueError(_("Could not create module key"))
+        rc = semanage_module_install_file(self.sh, file)
+        if rc >= 0:
+            self.commit()
 
-                      rc = semanage_module_key_set_name(self.sh, key, m)
-                      if rc < 0:
-                              raise ValueError(_("Could not set module key name"))
+    def set_enabled(self, module, enable):
+        for m in module.split():
+            rc, key = semanage_module_key_create(self.sh)
+            if rc < 0:
+                raise ValueError(_("Could not create module key"))
 
-                      rc = semanage_module_set_enabled(self.sh, key, enable)
-                      if rc < 0:
-                              if enable:
-                                  raise ValueError(_("Could not enable module %s") % m)
-                              else:
-                                  raise ValueError(_("Could not disable module %s") % m)
-               self.commit()
+            rc = semanage_module_key_set_name(self.sh, key, m)
+            if rc < 0:
+                raise ValueError(_("Could not set module key name"))
 
-	def modify(self, file):
-               rc = semanage_module_update_file(self.sh, file);
-               if rc >= 0:
-                      self.commit()
+            rc = semanage_module_set_enabled(self.sh, key, enable)
+            if rc < 0:
+                if enable:
+                    raise ValueError(_("Could not enable module %s") % m)
+                else:
+                    raise ValueError(_("Could not disable module %s") % m)
+        self.commit()
 
-	def delete(self, module, priority):
-               rc = semanage_set_default_priority(self.sh, priority)
-               if rc < 0:
-                       raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
+    def modify(self, file):
+        rc = semanage_module_update_file(self.sh, file)
+        if rc >= 0:
+            self.commit()
 
-               for m in module.split():
-                      rc = semanage_module_remove(self.sh, m)
-                      if rc < 0 and rc != -2:
-                             raise ValueError(_("Could not remove module %s (remove failed)") % m)
+    def delete(self, module, priority):
+        rc = semanage_set_default_priority(self.sh, priority)
+        if rc < 0:
+            raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
 
-               self.commit()
+        for m in module.split():
+            rc = semanage_module_remove(self.sh, m)
+            if rc < 0 and rc != -2:
+                raise ValueError(_("Could not remove module %s (remove failed)") % m)
 
-	def deleteall(self):
-                l = map(lambda x: x[0], filter(lambda t: t[1] == 0, self.get_all()))
-                for m in l:
-                        self.enable(m)
+        self.commit()
+
+    def deleteall(self):
+        l = map(lambda x: x[0], filter(lambda t: t[1] == 0, self.get_all()))
+        for m in l:
+            self.set_enabled(m, True)
+
 
 class dontauditClass(semanageRecords):
-	def __init__(self, store):
-               semanageRecords.__init__(self, store)
 
-	def toggle(self, dontaudit):
-               if dontaudit not in [ "on", "off" ]:
-                      raise ValueError(_("dontaudit requires either 'on' or 'off'"))
-               self.begin()
-               rc = semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
-               self.commit()
-               
+    def __init__(self, store):
+        semanageRecords.__init__(self, store)
+
+    def toggle(self, dontaudit):
+        if dontaudit not in ["on", "off"]:
+            raise ValueError(_("dontaudit requires either 'on' or 'off'"))
+        self.begin()
+        rc = semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
+        self.commit()
+
+
 class permissiveRecords(semanageRecords):
-	def __init__(self, store):
-               semanageRecords.__init__(self, store)
 
-	def get_all(self):
-               l = []
-               (rc, mlist, number) = semanage_module_list(self.sh)
-               if rc < 0:
-                      raise ValueError(_("Could not list SELinux modules"))
+    def __init__(self, store):
+        semanageRecords.__init__(self, store)
 
-               for i in range(number):
-                      mod = semanage_module_list_nth(mlist, i)
-                      name = semanage_module_get_name(mod)
-                      if name and name.startswith("permissive_"):
-                             l.append(name.split("permissive_")[1])
-               return l
+    def get_all(self):
+        l = []
+        (rc, mlist, number) = semanage_module_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list SELinux modules"))
 
-	def list(self, heading = 1, locallist = 0):
-		all = map(lambda y: y["name"], filter(lambda x: x["permissive"], sepolicy.info(sepolicy.TYPE)))
-		if len(all) == 0:
-			return 
+        for i in range(number):
+            mod = semanage_module_list_nth(mlist, i)
+            name = semanage_module_get_name(mod)
+            if name and name.startswith("permissive_"):
+                l.append(name.split("permissive_")[1])
+        return l
 
-		if heading:
-			print "\n%-25s\n" % (_("Builtin Permissive Types"))
-		customized = self.get_all()
-                for t in all:
-			if t not in customized:
-				print t
+    def list(self, heading=1, locallist=0):
+        all = map(lambda y: y["name"], filter(lambda x: x["permissive"], sepolicy.info(sepolicy.TYPE)))
+        if len(all) == 0:
+            return
 
-		if len(customized) == 0:
-			return 
+        if heading:
+            print "\n%-25s\n" % (_("Builtin Permissive Types"))
+        customized = self.get_all()
+        for t in all:
+            if t not in customized:
+                print t
 
-		if heading:
-			print "\n%-25s\n" % (_("Customized Permissive Types"))
-		for t in customized:
-			print t
+        if len(customized) == 0:
+            return
 
-	def add(self, type):
-               import glob
-	       try:
-		       import sepolgen.module as module
-	       except ImportError:
-		       raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro."))
-		
-               name = "permissive_%s" % type
-               modtxt = "(typepermissive %s)" % type
+        if heading:
+            print "\n%-25s\n" % (_("Customized Permissive Types"))
+        for t in customized:
+            print t
 
-               rc = semanage_module_install(self.sh, modtxt, len(modtxt), name, "cil");
-               if rc >= 0:
-                      self.commit()
+    def add(self, type):
+        import glob
+        try:
+            import sepolgen.module as module
+        except ImportError:
+            raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel patckage.\n# yum install policycoreutils-devel\nOr similar for your distro."))
 
-               if rc < 0:
-			raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name)
+        name = "permissive_%s" % type
+        modtxt = "(typepermissive %s)" % type
 
-	def delete(self, name):
-               for n in name.split():
-                      rc = semanage_module_remove(self.sh, "permissive_%s" % n)
-                      if rc < 0:
-                             raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name)
-                      
-               self.commit()
-			
-	def deleteall(self):
-               l = self.get_all()
-               if len(l) > 0:
-                      all = " ".join(l)
-                      self.delete(all)
+        rc = semanage_module_install(self.sh, modtxt, len(modtxt), name, "cil")
+        if rc >= 0:
+            self.commit()
+
+        if rc < 0:
+            raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name)
+
+    def delete(self, name):
+        for n in name.split():
+            rc = semanage_module_remove(self.sh, "permissive_%s" % n)
+            if rc < 0:
+                raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name)
+
+        self.commit()
+
+    def deleteall(self):
+        l = self.get_all()
+        if len(l) > 0:
+            all = " ".join(l)
+            self.delete(all)
+
 
 class loginRecords(semanageRecords):
-	def __init__(self, store = ""):
-		semanageRecords.__init__(self, store)
-		self.oldsename  = None
-		self.oldserange = None
-		self.sename  = None
-		self.serange = None
 
-	def __add(self, name, sename, serange):
-		rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
-		if sename == "":
-			sename = "user_u"
-			
-		userrec = seluserRecords()
-		range, (rc, oldserole) = userrec.get(self.oldsename)
-		range, (rc, serole) = userrec.get(sename)
+    def __init__(self, store=""):
+        semanageRecords.__init__(self, store)
+        self.oldsename = None
+        self.oldserange = None
+        self.sename = None
+        self.serange = None
 
-		if is_mls_enabled == 1:
-			if serange != "":
-				serange = untranslate(serange)
-			else:
-                           serange = range
-			
-		(rc, k) = semanage_seuser_key_create(self.sh, name)
-		if rc < 0:
-			raise ValueError(_("Could not create a key for %s") % name)
+    def __add(self, name, sename, serange):
+        rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
+        if sename == "":
+            sename = "user_u"
 
-		(rc, exists) = semanage_seuser_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if login mapping for %s is defined") % name)
-		if exists:
-			raise ValueError(_("Login mapping for %s is already defined") % name)
-                if name[0] == '%':
-                       try:
-                              grp.getgrnam(name[1:])
-                       except:
-                              raise ValueError(_("Linux Group %s does not exist") % name[1:])
-                else:
-                       try:
-                              pwd.getpwnam(name)
-                       except:
-                              raise ValueError(_("Linux User %s does not exist") % name)
+        userrec = seluserRecords()
+        range, (rc, oldserole) = userrec.get(self.oldsename)
+        range, (rc, serole) = userrec.get(sename)
 
-                (rc, u) = semanage_seuser_create(self.sh)
-                if rc < 0:
-                       raise ValueError(_("Could not create login mapping for %s") % name)
+        if is_mls_enabled == 1:
+            if serange != "":
+                serange = untranslate(serange)
+            else:
+                serange = range
 
-                rc = semanage_seuser_set_name(self.sh, u, name)
-                if rc < 0:
-                       raise ValueError(_("Could not set name for %s") % name)
+        (rc, k) = semanage_seuser_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
 
-                if (is_mls_enabled == 1) and (serange != ""):
-                       rc = semanage_seuser_set_mlsrange(self.sh, u, serange)
-                       if rc < 0:
-                              raise ValueError(_("Could not set MLS range for %s") % name)
+        (rc, exists) = semanage_seuser_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+        if exists:
+            raise ValueError(_("Login mapping for %s is already defined") % name)
+        if name[0] == '%':
+            try:
+                grp.getgrnam(name[1:])
+            except:
+                raise ValueError(_("Linux Group %s does not exist") % name[1:])
+        else:
+            try:
+                pwd.getpwnam(name)
+            except:
+                raise ValueError(_("Linux User %s does not exist") % name)
 
-                rc = semanage_seuser_set_sename(self.sh, u, sename)
-                if rc < 0:
-                       raise ValueError(_("Could not set SELinux user for %s") % name)
+        (rc, u) = semanage_seuser_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create login mapping for %s") % name)
 
-                rc = semanage_seuser_modify_local(self.sh, k, u)
-                if rc < 0:
-                       raise ValueError(_("Could not add login mapping for %s") % name)
+        rc = semanage_seuser_set_name(self.sh, u, name)
+        if rc < 0:
+            raise ValueError(_("Could not set name for %s") % name)
 
-		semanage_seuser_key_free(k)
-		semanage_seuser_free(u)
-		self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
+        if (is_mls_enabled == 1) and (serange != ""):
+            rc = semanage_seuser_set_mlsrange(self.sh, u, serange)
+            if rc < 0:
+                raise ValueError(_("Could not set MLS range for %s") % name)
 
-	def add(self, name, sename, serange):
-		try:
-			self.begin()
-			self.__add(name, sename, serange)
-			self.commit()
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
+        rc = semanage_seuser_set_sename(self.sh, u, sename)
+        if rc < 0:
+            raise ValueError(_("Could not set SELinux user for %s") % name)
 
-	def __modify(self, name, sename = "", serange = ""):
-		rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
-		if sename == "" and serange == "":
-                      raise ValueError(_("Requires seuser or serange"))
+        rc = semanage_seuser_modify_local(self.sh, k, u)
+        if rc < 0:
+            raise ValueError(_("Could not add login mapping for %s") % name)
 
-		userrec = seluserRecords()
-		range, (rc, oldserole) = userrec.get(self.oldsename)
+        semanage_seuser_key_free(k)
+        semanage_seuser_free(u)
+        self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
 
-		if sename != "":
-			range, (rc, serole) = userrec.get(sename)
-		else:
-			serole=oldserole
+    def add(self, name, sename, serange):
+        try:
+            self.begin()
+            self.__add(name, sename, serange)
+            self.commit()
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
 
-		if serange != "":
-			self.serange=serange
-		else:
-			self.serange=range
+    def __modify(self, name, sename="", serange=""):
+        rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
+        if sename == "" and serange == "":
+            raise ValueError(_("Requires seuser or serange"))
 
-		(rc, k) = semanage_seuser_key_create(self.sh, name)
-		if rc < 0:
-		       raise ValueError(_("Could not create a key for %s") % name)
+        userrec = seluserRecords()
+        range, (rc, oldserole) = userrec.get(self.oldsename)
 
-		(rc, exists) = semanage_seuser_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if login mapping for %s is defined") % name)
-		if not exists:
-			raise ValueError(_("Login mapping for %s is not defined") % name)
-		
-		(rc, u) = semanage_seuser_query(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not query seuser for %s") % name)
-		
-		self.oldserange = semanage_seuser_get_mlsrange(u)
-		self.oldsename = semanage_seuser_get_sename(u)
-		if (is_mls_enabled == 1) and (serange != ""):
-			semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
+        if sename != "":
+            range, (rc, serole) = userrec.get(sename)
+        else:
+            serole = oldserole
 
-		if sename != "":
-			semanage_seuser_set_sename(self.sh, u, sename)
-		else:
-			self.sename = self.oldsename
-			
-		rc = semanage_seuser_modify_local(self.sh, k, u)
-		if rc < 0:
-			raise ValueError(_("Could not modify login mapping for %s") % name)
+        if serange != "":
+            self.serange = serange
+        else:
+            self.serange = range
 
-		semanage_seuser_key_free(k)
-		semanage_seuser_free(u)
-		self.mylog.log("login", name,sename=self.sename,serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
+        (rc, k) = semanage_seuser_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
 
-	def modify(self, name, sename = "", serange = ""):
-		try:
-                        self.begin()
-                        self.__modify(name, sename, serange)
-                        self.commit()
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
+        (rc, exists) = semanage_seuser_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+        if not exists:
+            raise ValueError(_("Login mapping for %s is not defined") % name)
 
-	def __delete(self, name):
-		rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
-		userrec = seluserRecords()
-		range, (rc, oldserole) = userrec.get(self.oldsename)
+        (rc, u) = semanage_seuser_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query seuser for %s") % name)
 
-		(rc, k) = semanage_seuser_key_create(self.sh, name)
-		if rc < 0:
-			raise ValueError(_("Could not create a key for %s") % name)
+        self.oldserange = semanage_seuser_get_mlsrange(u)
+        self.oldsename = semanage_seuser_get_sename(u)
+        if (is_mls_enabled == 1) and (serange != ""):
+            semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
 
-		(rc, exists) = semanage_seuser_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if login mapping for %s is defined") % name)
-		if not exists:
-			raise ValueError(_("Login mapping for %s is not defined") % name)
-		
-		(rc, exists) = semanage_seuser_exists_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if login mapping for %s is defined") % name)
-		if not exists:
-			raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
-		
-		rc = semanage_seuser_del_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not delete login mapping for %s") % name)
-		
-		semanage_seuser_key_free(k)
+        if sename != "":
+            semanage_seuser_set_sename(self.sh, u, sename)
+            self.sename = sename
+        else:
+            self.sename = self.oldsename
 
-		rec, self.sename, self.serange = selinux.getseuserbyname("__default__")
-		range, (rc, serole) = userrec.get(self.sename)
+        rc = semanage_seuser_modify_local(self.sh, k, u)
+        if rc < 0:
+            raise ValueError(_("Could not modify login mapping for %s") % name)
 
-		self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange);
+        semanage_seuser_key_free(k)
+        semanage_seuser_free(u)
+        self.mylog.log("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
 
-	def delete(self, name):
-		try:
-			self.begin()
-			self.__delete(name)
-			self.commit()
+    def modify(self, name, sename="", serange=""):
+        try:
+            self.begin()
+            self.__modify(name, sename, serange)
+            self.commit()
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
 
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
-		
-	def deleteall(self):
-		(rc, ulist) = semanage_seuser_list_local(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list login mappings"))
+    def __delete(self, name):
+        rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
+        userrec = seluserRecords()
+        range, (rc, oldserole) = userrec.get(self.oldsename)
 
-		try:
-			self.begin()
-			for u in ulist:
-				self.__delete(semanage_seuser_get_name(u))
-			self.commit()
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
-		
-	def get_all_logins(self):
-		ddict = {}
-		self.logins_path = selinux.selinux_policy_root() + "/logins"
-		for path,dirs,files in os.walk(self.logins_path):
-			if path == self.logins_path:
-				for name in files:
-					try:
-						fd = open(path + "/" + name)
-						rec = fd.read().rstrip().split(":")
-						fd.close()
-						ddict[name] = (rec[1], rec[2], rec[0])
-					except IndexError:
-						pass
-		return ddict
+        (rc, k) = semanage_seuser_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
 
-	def get_all(self, locallist = 0):
-		ddict = {}
-                if locallist:
-                       (rc, self.ulist) = semanage_seuser_list_local(self.sh)
-                else:
-                       (rc, self.ulist) = semanage_seuser_list(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list login mappings"))
+        (rc, exists) = semanage_seuser_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+        if not exists:
+            raise ValueError(_("Login mapping for %s is not defined") % name)
 
-		for u in self.ulist:
-			name = semanage_seuser_get_name(u)
-			ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*")
-		return ddict
+        (rc, exists) = semanage_seuser_exists_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
+        if not exists:
+            raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
 
-        def customized(self):
-                l = []
-                ddict = self.get_all(True)
-                keys = ddict.keys()
-                keys.sort()
-                for k in keys:
-                       l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k))
-                return l
+        rc = semanage_seuser_del_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not delete login mapping for %s") % name)
 
-	def list(self,heading = 1, locallist = 0):
-		ddict = self.get_all(locallist)
-		ldict = self.get_all_logins()
-		lkeys = ldict.keys()
-		keys = ddict.keys()
-		if len(keys) == 0 and len(lkeys) == 0:
-			return 
-		keys.sort()
-		lkeys.sort()
+        semanage_seuser_key_free(k)
 
-		if is_mls_enabled == 1:
-			if heading:
-				print "\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))
-			for k in keys:
-				u = ddict[k]
-				print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
-			if len(lkeys):
-				print "\nLocal customization in %s" % self.logins_path
-				
-			for k in lkeys:
-				u = ldict[k]
-				print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
-		else:
-			if heading:
-				print "\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))
-			for k in keys:
-				print "%-25s %-25s" % (k, ddict[k][0])
+        rec, self.sename, self.serange = selinux.getseuserbyname("__default__")
+        range, (rc, serole) = userrec.get(self.sename)
+
+        self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange)
+
+    def delete(self, name):
+        try:
+            self.begin()
+            self.__delete(name)
+            self.commit()
+
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
+
+    def deleteall(self):
+        (rc, ulist) = semanage_seuser_list_local(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list login mappings"))
+
+        try:
+            self.begin()
+            for u in ulist:
+                self.__delete(semanage_seuser_get_name(u))
+            self.commit()
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
+
+    def get_all_logins(self):
+        ddict = {}
+        self.logins_path = selinux.selinux_policy_root() + "/logins"
+        for path, dirs, files in os.walk(self.logins_path):
+            if path == self.logins_path:
+                for name in files:
+                    try:
+                        fd = open(path + "/" + name)
+                        rec = fd.read().rstrip().split(":")
+                        fd.close()
+                        ddict[name] = (rec[1], rec[2], rec[0])
+                    except IndexError:
+                        pass
+        return ddict
+
+    def get_all(self, locallist=0):
+        ddict = {}
+        if locallist:
+            (rc, self.ulist) = semanage_seuser_list_local(self.sh)
+        else:
+            (rc, self.ulist) = semanage_seuser_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list login mappings"))
+
+        for u in self.ulist:
+            name = semanage_seuser_get_name(u)
+            ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*")
+        return ddict
+
+    def customized(self):
+        l = []
+        ddict = self.get_all(True)
+        keys = ddict.keys()
+        keys.sort()
+        for k in keys:
+            l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k))
+        return l
+
+    def list(self, heading=1, locallist=0):
+        ddict = self.get_all(locallist)
+        ldict = self.get_all_logins()
+        lkeys = ldict.keys()
+        keys = ddict.keys()
+        if len(keys) == 0 and len(lkeys) == 0:
+            return
+        keys.sort()
+        lkeys.sort()
+
+        if is_mls_enabled == 1:
+            if heading:
+                print "\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service"))
+            for k in keys:
+                u = ddict[k]
+                print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
+            if len(lkeys):
+                print "\nLocal customization in %s" % self.logins_path
+
+            for k in lkeys:
+                u = ldict[k]
+                print "%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2])
+        else:
+            if heading:
+                print "\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))
+            for k in keys:
+                print "%-25s %-25s" % (k, ddict[k][0])
+
 
 class seluserRecords(semanageRecords):
-	def __init__(self, store = ""):
-		semanageRecords.__init__(self, store)
 
-	def get(self, name):
-                (rc, k) = semanage_user_key_create(self.sh, name)
-                if rc < 0:
-                       raise ValueError(_("Could not create a key for %s") % name)
-                (rc, exists) = semanage_user_exists(self.sh, k)
-                if rc < 0:
-                       raise ValueError(_("Could not check if SELinux user %s is defined") % name)
-                (rc, u) = semanage_user_query(self.sh, k)
-                if rc < 0:
-                       raise ValueError(_("Could not query user for %s") % name)
-                serange = semanage_user_get_mlsrange(u)
-                serole = semanage_user_get_roles(self.sh,u)
-		semanage_user_key_free(k)
-		semanage_user_free(u)
-		return serange, serole
-                
-	def __add(self, name, roles, selevel, serange, prefix):
-		if is_mls_enabled == 1:
-			if serange == "":
-				serange = "s0"
-			else:
-				serange = untranslate(serange)
-			
-			if selevel == "":
-				selevel = "s0"
-			else:
-				selevel = untranslate(selevel)
-			
-                if len(roles) < 1:
-                       raise ValueError(_("You must add at least one role for %s") % name)
-                       
-                (rc, k) = semanage_user_key_create(self.sh, name)
-                if rc < 0:
-                       raise ValueError(_("Could not create a key for %s") % name)
+    def __init__(self, store=""):
+        semanageRecords.__init__(self, store)
 
-                (rc, exists) = semanage_user_exists(self.sh, k)
-                if rc < 0:
-                       raise ValueError(_("Could not check if SELinux user %s is defined") % name)
-                if exists:
-                       raise ValueError(_("SELinux user %s is already defined") % name)
+    def get(self, name):
+        (rc, k) = semanage_user_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
+        (rc, exists) = semanage_user_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+        (rc, u) = semanage_user_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query user for %s") % name)
+        serange = semanage_user_get_mlsrange(u)
+        serole = semanage_user_get_roles(self.sh, u)
+        semanage_user_key_free(k)
+        semanage_user_free(u)
+        return serange, serole
 
-                (rc, u) = semanage_user_create(self.sh)
-                if rc < 0:
-                       raise ValueError(_("Could not create SELinux user for %s") % name)
+    def __add(self, name, roles, selevel, serange, prefix):
+        if is_mls_enabled == 1:
+            if serange == "":
+                serange = "s0"
+            else:
+                serange = untranslate(serange)
 
-                rc = semanage_user_set_name(self.sh, u, name)
-                if rc < 0:
-                       raise ValueError(_("Could not set name for %s") % name)
+            if selevel == "":
+                selevel = "s0"
+            else:
+                selevel = untranslate(selevel)
 
-                for r in roles:
-                       rc = semanage_user_add_role(self.sh, u, r)
-                       if rc < 0:
-                              raise ValueError(_("Could not add role %s for %s") % (r, name))
+        if len(roles) < 1:
+            raise ValueError(_("You must add at least one role for %s") % name)
 
-                if is_mls_enabled == 1:
-                       rc = semanage_user_set_mlsrange(self.sh, u, serange)
-                       if rc < 0:
-                              raise ValueError(_("Could not set MLS range for %s") % name)
+        (rc, k) = semanage_user_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
 
-                       rc = semanage_user_set_mlslevel(self.sh, u, selevel)
-                       if rc < 0:
-                              raise ValueError(_("Could not set MLS level for %s") % name)
-                rc = semanage_user_set_prefix(self.sh, u, prefix)
-                if rc < 0:
-                       raise ValueError(_("Could not add prefix %s for %s") % (r, prefix))
-                (rc, key) = semanage_user_key_extract(self.sh,u)
-                if rc < 0:
-                       raise ValueError(_("Could not extract key for %s") % name)
+        (rc, exists) = semanage_user_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+        if exists:
+            raise ValueError(_("SELinux user %s is already defined") % name)
 
-                rc = semanage_user_modify_local(self.sh, k, u)
-                if rc < 0:
-                       raise ValueError(_("Could not add SELinux user %s") % name)
+        (rc, u) = semanage_user_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create SELinux user for %s") % name)
 
-                semanage_user_key_free(k)
-                semanage_user_free(u)
-		self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange)
+        rc = semanage_user_set_name(self.sh, u, name)
+        if rc < 0:
+            raise ValueError(_("Could not set name for %s") % name)
 
-	def add(self, name, roles, selevel, serange, prefix):
-		serole = " ".join(roles)
-		try:
-			self.begin()
-			self.__add( name, roles, selevel, serange, prefix)
-			self.commit()
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
+        for r in roles:
+            rc = semanage_user_add_role(self.sh, u, r)
+            if rc < 0:
+                raise ValueError(_("Could not add role %s for %s") % (r, name))
 
-        def __modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
-		oldserole = ""
-		oldserange = ""
-		newroles = string.join(roles, ' ');
-                if prefix == "" and len(roles) == 0  and serange == "" and selevel == "":
-                       if is_mls_enabled == 1:
-                              raise ValueError(_("Requires prefix, roles, level or range"))
-                       else:
-                              raise ValueError(_("Requires prefix or roles"))
+        if is_mls_enabled == 1:
+            rc = semanage_user_set_mlsrange(self.sh, u, serange)
+            if rc < 0:
+                raise ValueError(_("Could not set MLS range for %s") % name)
 
-                (rc, k) = semanage_user_key_create(self.sh, name)
-                if rc < 0:
-                       raise ValueError(_("Could not create a key for %s") % name)
+            rc = semanage_user_set_mlslevel(self.sh, u, selevel)
+            if rc < 0:
+                raise ValueError(_("Could not set MLS level for %s") % name)
+        rc = semanage_user_set_prefix(self.sh, u, prefix)
+        if rc < 0:
+            raise ValueError(_("Could not add prefix %s for %s") % (r, prefix))
+        (rc, key) = semanage_user_key_extract(self.sh, u)
+        if rc < 0:
+            raise ValueError(_("Could not extract key for %s") % name)
 
-                (rc, exists) = semanage_user_exists(self.sh, k)
-                if rc < 0:
-                       raise ValueError(_("Could not check if SELinux user %s is defined") % name)
-                if not exists:
-                       raise ValueError(_("SELinux user %s is not defined") % name)
+        rc = semanage_user_modify_local(self.sh, k, u)
+        if rc < 0:
+            raise ValueError(_("Could not add SELinux user %s") % name)
 
-                (rc, u) = semanage_user_query(self.sh, k)
-                if rc < 0:
-                       raise ValueError(_("Could not query user for %s") % name)
+        semanage_user_key_free(k)
+        semanage_user_free(u)
+        self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange)
 
-                oldserange = semanage_user_get_mlsrange(u)
-                (rc, rlist) = semanage_user_get_roles(self.sh, u)
-                if rc >= 0:
-                       oldserole = string.join(rlist, ' ');
+    def add(self, name, roles, selevel, serange, prefix):
+        serole = " ".join(roles)
+        try:
+            self.begin()
+            self.__add(name, roles, selevel, serange, prefix)
+            self.commit()
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
 
-                if (is_mls_enabled == 1) and (serange != ""):
-                       semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
-                if (is_mls_enabled == 1) and (selevel != ""):
-                       semanage_user_set_mlslevel(self.sh, u, untranslate(selevel))
+    def __modify(self, name, roles=[], selevel="", serange="", prefix=""):
+        oldserole = ""
+        oldserange = ""
+        newroles = string.join(roles, ' ')
+        if prefix == "" and len(roles) == 0 and serange == "" and selevel == "":
+            if is_mls_enabled == 1:
+                raise ValueError(_("Requires prefix, roles, level or range"))
+            else:
+                raise ValueError(_("Requires prefix or roles"))
 
-                if prefix != "":
-                       semanage_user_set_prefix(self.sh, u, prefix)
+        (rc, k) = semanage_user_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
 
-                if len(roles) != 0:
-                       for r in rlist:
-                              if r not in roles:
-                                     semanage_user_del_role(u, r)
-                       for r in roles:
-                              if r not in rlist:
-                                     semanage_user_add_role(self.sh, u, r)
+        (rc, exists) = semanage_user_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+        if not exists:
+            raise ValueError(_("SELinux user %s is not defined") % name)
 
-                rc = semanage_user_modify_local(self.sh, k, u)
-                if rc < 0:
-                       raise ValueError(_("Could not modify SELinux user %s") % name)
+        (rc, u) = semanage_user_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query user for %s") % name)
 
-		semanage_user_key_free(k)
-		semanage_user_free(u)
-	
-		role=",".join(newroles.split())
-		oldserole=",".join(oldserole.split())
-		self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange)
+        oldserange = semanage_user_get_mlsrange(u)
+        (rc, rlist) = semanage_user_get_roles(self.sh, u)
+        if rc >= 0:
+            oldserole = string.join(rlist, ' ')
 
+        if (is_mls_enabled == 1) and (serange != ""):
+            semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
+        if (is_mls_enabled == 1) and (selevel != ""):
+            semanage_user_set_mlslevel(self.sh, u, untranslate(selevel))
 
-	def modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
-		try:
-                        self.begin()
-                        self.__modify(name, roles, selevel, serange, prefix)
-                        self.commit()
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
+        if prefix != "":
+            semanage_user_set_prefix(self.sh, u, prefix)
 
-	def __delete(self, name):
-               (rc, k) = semanage_user_key_create(self.sh, name)
-               if rc < 0:
-                      raise ValueError(_("Could not create a key for %s") % name)
-			
-               (rc, exists) = semanage_user_exists(self.sh, k)
-               if rc < 0:
-                      raise ValueError(_("Could not check if SELinux user %s is defined") % name)		
-               if not exists:
-                      raise ValueError(_("SELinux user %s is not defined") % name)
+        if len(roles) != 0:
+            for r in rlist:
+                if r not in roles:
+                    semanage_user_del_role(u, r)
+            for r in roles:
+                if r not in rlist:
+                    semanage_user_add_role(self.sh, u, r)
 
-               (rc, exists) = semanage_user_exists_local(self.sh, k)
-               if rc < 0:
-                      raise ValueError(_("Could not check if SELinux user %s is defined") % name)
-               if not exists:
-                      raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
-			
-	       (rc, u) = semanage_user_query(self.sh, k)
-	       if rc < 0:
-                       raise ValueError(_("Could not query user for %s") % name)
-	       oldserange = semanage_user_get_mlsrange(u)
-	       (rc, rlist) = semanage_user_get_roles(self.sh, u)
-	       oldserole = ",".join(rlist)
+        rc = semanage_user_modify_local(self.sh, k, u)
+        if rc < 0:
+            raise ValueError(_("Could not modify SELinux user %s") % name)
 
-               rc = semanage_user_del_local(self.sh, k)
-               if rc < 0:
-                      raise ValueError(_("Could not delete SELinux user %s") % name)
+        semanage_user_key_free(k)
+        semanage_user_free(u)
 
-               semanage_user_key_free(k)		
-	       semanage_user_free(u)
+        role = ",".join(newroles.split())
+        oldserole = ",".join(oldserole.split())
+        self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange)
 
-	       self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole)
+    def modify(self, name, roles=[], selevel="", serange="", prefix=""):
+        try:
+            self.begin()
+            self.__modify(name, roles, selevel, serange, prefix)
+            self.commit()
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
 
-	def delete(self, name):
-		try:
-                        self.begin()
-                        self.__delete(name)
-                        self.commit()
+    def __delete(self, name):
+        (rc, k) = semanage_user_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
 
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
-		
-	def deleteall(self):
-		(rc, ulist) = semanage_user_list_local(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list login mappings"))
+        (rc, exists) = semanage_user_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+        if not exists:
+            raise ValueError(_("SELinux user %s is not defined") % name)
 
-		try:
-			self.begin()
-			for u in ulist:
-				self.__delete(semanage_user_get_name(u))
-			self.commit()
-		except ValueError, error:
-			self.mylog.commit(0)
-			raise error
+        (rc, exists) = semanage_user_exists_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
+        if not exists:
+            raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
 
-	def get_all(self, locallist = 0):
-		ddict = {}
-                if locallist:
-                       (rc, self.ulist) = semanage_user_list_local(self.sh)
-                else:
-                       (rc, self.ulist) = semanage_user_list(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list SELinux users"))
+        (rc, u) = semanage_user_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query user for %s") % name)
+        oldserange = semanage_user_get_mlsrange(u)
+        (rc, rlist) = semanage_user_get_roles(self.sh, u)
+        oldserole = ",".join(rlist)
 
-		for u in self.ulist:
-			name = semanage_user_get_name(u)
-			(rc, rlist) = semanage_user_get_roles(self.sh, u)
-			if rc < 0:
-				raise ValueError(_("Could not list roles for user %s") % name)
+        rc = semanage_user_del_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not delete SELinux user %s") % name)
 
-			roles = string.join(rlist, ' ');
-			ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles)
+        semanage_user_key_free(k)
+        semanage_user_free(u)
 
-		return ddict
+        self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole)
 
-        def customized(self):
-                l = []
-                ddict = self.get_all(True)
-                keys = ddict.keys()
-                keys.sort()
-                for k in keys:
-                       l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k))
-                return l
+    def delete(self, name):
+        try:
+            self.begin()
+            self.__delete(name)
+            self.commit()
 
-	def list(self, heading = 1, locallist = 0):
-		ddict = self.get_all(locallist)
-		keys = ddict.keys()
-		if len(keys) == 0:
-			return 
-		keys.sort()
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
 
-		if is_mls_enabled == 1:
-			if heading:
-				print "\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))
-				print "%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))
-			for k in keys:
-				print "%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])
-		else:
-			if heading:
-				print "%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))
-			for k in keys:
-				print "%-15s %s" % (k, ddict[k][3])
+    def deleteall(self):
+        (rc, ulist) = semanage_user_list_local(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list login mappings"))
+
+        try:
+            self.begin()
+            for u in ulist:
+                self.__delete(semanage_user_get_name(u))
+            self.commit()
+        except ValueError, error:
+            self.mylog.commit(0)
+            raise error
+
+    def get_all(self, locallist=0):
+        ddict = {}
+        if locallist:
+            (rc, self.ulist) = semanage_user_list_local(self.sh)
+        else:
+            (rc, self.ulist) = semanage_user_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list SELinux users"))
+
+        for u in self.ulist:
+            name = semanage_user_get_name(u)
+            (rc, rlist) = semanage_user_get_roles(self.sh, u)
+            if rc < 0:
+                raise ValueError(_("Could not list roles for user %s") % name)
+
+            roles = string.join(rlist, ' ')
+            ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles)
+
+        return ddict
+
+    def customized(self):
+        l = []
+        ddict = self.get_all(True)
+        keys = ddict.keys()
+        keys.sort()
+        for k in keys:
+            l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k))
+        return l
+
+    def list(self, heading=1, locallist=0):
+        ddict = self.get_all(locallist)
+        keys = ddict.keys()
+        if len(keys) == 0:
+            return
+        keys.sort()
+
+        if is_mls_enabled == 1:
+            if heading:
+                print "\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))
+                print "%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))
+            for k in keys:
+                print "%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])
+        else:
+            if heading:
+                print "%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))
+            for k in keys:
+                print "%-15s %s" % (k, ddict[k][3])
+
 
 class portRecords(semanageRecords):
-	try:
-		valid_types =  sepolicy.info(sepolicy.ATTRIBUTE,"port_type")[0]["types"]
-	except RuntimeError:
-		valid_types = []
+    try:
+        valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "port_type")[0]["types"]
+    except RuntimeError:
+        valid_types = []
 
-	def __init__(self, store = ""):
-		semanageRecords.__init__(self, store)
+    def __init__(self, store=""):
+        semanageRecords.__init__(self, store)
 
-	def __genkey(self, port, proto):
-		if proto == "tcp":
-			proto_d = SEMANAGE_PROTO_TCP
-		else:
-			if proto == "udp":
-				proto_d = SEMANAGE_PROTO_UDP
-			else:
-				raise ValueError(_("Protocol udp or tcp is required"))
-		if port == "":
-			raise ValueError(_("Port is required"))
-			
-		ports = port.split("-")
-		if len(ports) == 1:
-			high = low = int(ports[0])
-		else:
-			low = int(ports[0])
-			high = int(ports[1])
+    def __genkey(self, port, proto):
+        if proto == "tcp":
+            proto_d = SEMANAGE_PROTO_TCP
+        else:
+            if proto == "udp":
+                proto_d = SEMANAGE_PROTO_UDP
+            else:
+                raise ValueError(_("Protocol udp or tcp is required"))
+        if port == "":
+            raise ValueError(_("Port is required"))
 
-		if high > 65535:
-			raise ValueError(_("Invalid Port"))
+        ports = port.split("-")
+        if len(ports) == 1:
+            high = low = int(ports[0])
+        else:
+            low = int(ports[0])
+            high = int(ports[1])
 
-		(rc, k) = semanage_port_key_create(self.sh, low, high, proto_d)
-		if rc < 0:
-			raise ValueError(_("Could not create a key for %s/%s") % (proto, port))
-		return ( k, proto_d, low, high )
+        if high > 65535:
+            raise ValueError(_("Invalid Port"))
 
-	def __add(self, port, proto, serange, type):
-		if is_mls_enabled == 1:
-			if serange == "":
-				serange = "s0"
-			else:
-				serange = untranslate(serange)
-			
-		if type == "":
-			raise ValueError(_("Type is required"))
+        (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s/%s") % (proto, port))
+        return (k, proto_d, low, high)
 
-		if type not in self.valid_types:
-			raise ValueError(_("Type %s is invalid, must be a port type") % type)
+    def __add(self, port, proto, serange, type):
+        if is_mls_enabled == 1:
+            if serange == "":
+                serange = "s0"
+            else:
+                serange = untranslate(serange)
 
-		( k, proto_d, low, high ) = self.__genkey(port, proto)			
+        if type == "":
+            raise ValueError(_("Type is required"))
 
-		(rc, exists) = semanage_port_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
-		if exists:
-			raise ValueError(_("Port %s/%s already defined") % (proto, port))
+        if type not in self.valid_types:
+            raise ValueError(_("Type %s is invalid, must be a port type") % type)
 
-		(rc, p) = semanage_port_create(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not create port for %s/%s") % (proto, port))
-		
-		semanage_port_set_proto(p, proto_d)
-		semanage_port_set_range(p, low, high)
-		(rc, con) = semanage_context_create(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not create context for %s/%s") % (proto, port))
+        (k, proto_d, low, high) = self.__genkey(port, proto)
 
-		rc = semanage_context_set_user(self.sh, con, "system_u")
-		if rc < 0:
-			raise ValueError(_("Could not set user in port context for %s/%s") % (proto, port))
+        (rc, exists) = semanage_port_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+        if exists:
+            raise ValueError(_("Port %s/%s already defined") % (proto, port))
 
-		rc = semanage_context_set_role(self.sh, con, "object_r")
-		if rc < 0:
-			raise ValueError(_("Could not set role in port context for %s/%s") % (proto, port))
+        (rc, p) = semanage_port_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create port for %s/%s") % (proto, port))
 
-		rc = semanage_context_set_type(self.sh, con, type)
-		if rc < 0:
-			raise ValueError(_("Could not set type in port context for %s/%s") % (proto, port))
+        semanage_port_set_proto(p, proto_d)
+        semanage_port_set_range(p, low, high)
+        (rc, con) = semanage_context_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create context for %s/%s") % (proto, port))
 
-		if (is_mls_enabled == 1) and (serange != ""):
-			rc = semanage_context_set_mls(self.sh, con, serange)
-			if rc < 0:
-				raise ValueError(_("Could not set mls fields in port context for %s/%s") % (proto, port))
+        rc = semanage_context_set_user(self.sh, con, "system_u")
+        if rc < 0:
+            raise ValueError(_("Could not set user in port context for %s/%s") % (proto, port))
 
-		rc = semanage_port_set_con(self.sh, p, con)
-		if rc < 0:
-			raise ValueError(_("Could not set port context for %s/%s") % (proto, port))
+        rc = semanage_context_set_role(self.sh, con, "object_r")
+        if rc < 0:
+            raise ValueError(_("Could not set role in port context for %s/%s") % (proto, port))
 
-		rc = semanage_port_modify_local(self.sh, k, p)
-		if rc < 0:
-			raise ValueError(_("Could not add port %s/%s") % (proto, port))
-	
-		semanage_context_free(con)
-		semanage_port_key_free(k)
-		semanage_port_free(p)
+        rc = semanage_context_set_type(self.sh, con, type)
+        if rc < 0:
+            raise ValueError(_("Could not set type in port context for %s/%s") % (proto, port))
 
-	def add(self, port, proto, serange, type):
-                self.begin()
-                self.__add(port, proto, serange, type)
-                self.commit()
+        if (is_mls_enabled == 1) and (serange != ""):
+            rc = semanage_context_set_mls(self.sh, con, serange)
+            if rc < 0:
+                raise ValueError(_("Could not set mls fields in port context for %s/%s") % (proto, port))
 
-	def __modify(self, port, proto, serange, setype):
-		if serange == "" and setype == "":
-			if is_mls_enabled == 1:
-				raise ValueError(_("Requires setype or serange"))
-			else:
-				raise ValueError(_("Requires setype"))
+        rc = semanage_port_set_con(self.sh, p, con)
+        if rc < 0:
+            raise ValueError(_("Could not set port context for %s/%s") % (proto, port))
 
-		if setype and setype not in self.valid_types:
-			raise ValueError(_("Type %s is invalid, must be a port type") % setype)
+        rc = semanage_port_modify_local(self.sh, k, p)
+        if rc < 0:
+            raise ValueError(_("Could not add port %s/%s") % (proto, port))
 
-		( k, proto_d, low, high ) = self.__genkey(port, proto)
+        semanage_context_free(con)
+        semanage_port_key_free(k)
+        semanage_port_free(p)
 
-		(rc, exists) = semanage_port_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
-		if not exists:
-			raise ValueError(_("Port %s/%s is not defined") % (proto,port))
-	
-		(rc, p) = semanage_port_query(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not query port %s/%s") % (proto, port))
+    def add(self, port, proto, serange, type):
+        self.begin()
+        self.__add(port, proto, serange, type)
+        self.commit()
 
-		con = semanage_port_get_con(p)
-			
-		if (is_mls_enabled == 1) and (serange != ""):
-			semanage_context_set_mls(self.sh, con, untranslate(serange))
-		if setype != "":
-			semanage_context_set_type(self.sh, con, setype)
+    def __modify(self, port, proto, serange, setype):
+        if serange == "" and setype == "":
+            if is_mls_enabled == 1:
+                raise ValueError(_("Requires setype or serange"))
+            else:
+                raise ValueError(_("Requires setype"))
 
-		rc = semanage_port_modify_local(self.sh, k, p)
-		if rc < 0:
-			raise ValueError(_("Could not modify port %s/%s") % (proto, port))
+        if setype and setype not in self.valid_types:
+            raise ValueError(_("Type %s is invalid, must be a port type") % setype)
 
-		semanage_port_key_free(k)
-		semanage_port_free(p)
+        (k, proto_d, low, high) = self.__genkey(port, proto)
 
-	def modify(self, port, proto, serange, setype):
-                self.begin()
-                self.__modify(port, proto, serange, setype)
-                self.commit()
+        (rc, exists) = semanage_port_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+        if not exists:
+            raise ValueError(_("Port %s/%s is not defined") % (proto, port))
 
-	def deleteall(self):
-		(rc, plist) = semanage_port_list_local(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list the ports"))
+        (rc, p) = semanage_port_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query port %s/%s") % (proto, port))
 
-                self.begin()
+        con = semanage_port_get_con(p)
 
-		for port in plist:
-                       proto = semanage_port_get_proto(port)
-                       proto_str = semanage_port_get_proto_str(proto)
-                       low = semanage_port_get_low(port)
-                       high = semanage_port_get_high(port)
-                       port_str = "%s-%s" % (low, high)
-                       ( k, proto_d, low, high ) = self.__genkey(port_str , proto_str)
-                       if rc < 0:
-                              raise ValueError(_("Could not create a key for %s") % port_str)
+        if (is_mls_enabled == 1) and (serange != ""):
+            semanage_context_set_mls(self.sh, con, untranslate(serange))
+        if setype != "":
+            semanage_context_set_type(self.sh, con, setype)
 
-                       rc = semanage_port_del_local(self.sh, k)
-                       if rc < 0:
-                              raise ValueError(_("Could not delete the port %s") % port_str)
-                       semanage_port_key_free(k)
-	
-                self.commit()
+        rc = semanage_port_modify_local(self.sh, k, p)
+        if rc < 0:
+            raise ValueError(_("Could not modify port %s/%s") % (proto, port))
 
-	def __delete(self, port, proto):
-		( k, proto_d, low, high ) = self.__genkey(port, proto)
-		(rc, exists) = semanage_port_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
-		if not exists:
-			raise ValueError(_("Port %s/%s is not defined") % (proto, port))
-		
-		(rc, exists) = semanage_port_exists_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
-		if not exists:
-			raise ValueError(_("Port %s/%s is defined in policy, cannot be deleted") % (proto, port))
+        semanage_port_key_free(k)
+        semanage_port_free(p)
 
-		rc = semanage_port_del_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not delete port %s/%s") % (proto, port))
+    def modify(self, port, proto, serange, setype):
+        self.begin()
+        self.__modify(port, proto, serange, setype)
+        self.commit()
 
-		semanage_port_key_free(k)
+    def deleteall(self):
+        (rc, plist) = semanage_port_list_local(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list the ports"))
 
-	def delete(self, port, proto):
-                self.begin()
-                self.__delete(port, proto)
-                self.commit()
+        self.begin()
 
-	def get_all(self, locallist = 0):
-		ddict = {}
-                if locallist:
-                       (rc, self.plist) = semanage_port_list_local(self.sh)
-                else:
-                       (rc, self.plist) = semanage_port_list(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list ports"))
+        for port in plist:
+            proto = semanage_port_get_proto(port)
+            proto_str = semanage_port_get_proto_str(proto)
+            low = semanage_port_get_low(port)
+            high = semanage_port_get_high(port)
+            port_str = "%s-%s" % (low, high)
+            (k, proto_d, low, high) = self.__genkey(port_str, proto_str)
+            if rc < 0:
+                raise ValueError(_("Could not create a key for %s") % port_str)
 
-		for port in self.plist:
-			con = semanage_port_get_con(port)
-			ctype = semanage_context_get_type(con)
-			if ctype == "reserved_port_t":
-				continue
-			level = semanage_context_get_mls(con)
-			proto = semanage_port_get_proto(port)
-			proto_str = semanage_port_get_proto_str(proto)
-			low = semanage_port_get_low(port)
-			high = semanage_port_get_high(port)
-			ddict[(low, high, proto_str)] = (ctype, level)
-		return ddict
+            rc = semanage_port_del_local(self.sh, k)
+            if rc < 0:
+                raise ValueError(_("Could not delete the port %s") % port_str)
+            semanage_port_key_free(k)
 
-	def get_all_by_type(self, locallist = 0):
-		ddict = {}
-                if locallist:
-                       (rc, self.plist) = semanage_port_list_local(self.sh)
-                else:
-                       (rc, self.plist) = semanage_port_list(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list ports"))
+        self.commit()
 
-		for port in self.plist:
-			con = semanage_port_get_con(port)
-			ctype = semanage_context_get_type(con)
-			if ctype == "reserved_port_t":
-				continue
-			proto = semanage_port_get_proto(port)
-			proto_str = semanage_port_get_proto_str(proto)
-			low = semanage_port_get_low(port)
-			high = semanage_port_get_high(port)
-			if (ctype, proto_str) not in ddict.keys():
-				ddict[(ctype,proto_str)] = []
-			if low == high:
-				ddict[(ctype,proto_str)].append("%d" % low)
-			else:
-				ddict[(ctype,proto_str)].append("%d-%d" % (low, high))
-		return ddict
+    def __delete(self, port, proto):
+        (k, proto_d, low, high) = self.__genkey(port, proto)
+        (rc, exists) = semanage_port_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+        if not exists:
+            raise ValueError(_("Port %s/%s is not defined") % (proto, port))
 
-        def customized(self):
-                l = []
-		ddict = self.get_all(True)
-		keys = ddict.keys()
-		keys.sort()
-                for k in keys:
-                       if k[0] == k[1]:
-                              l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0]))
-                       else:
-                              l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1]))
-                return l
+        (rc, exists) = semanage_port_exists_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
+        if not exists:
+            raise ValueError(_("Port %s/%s is defined in policy, cannot be deleted") % (proto, port))
 
-	def list(self, heading = 1, locallist = 0):
-		ddict = self.get_all_by_type(locallist)
-		keys = ddict.keys()
-		if len(keys) == 0:
-			return 
-		keys.sort()
+        rc = semanage_port_del_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not delete port %s/%s") % (proto, port))
 
-		if heading:
-			print "%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))
-		for i in keys:
-			rec = "%-30s %-8s " % i
-			rec += "%s" % ddict[i][0]
-			for p in ddict[i][1:]:
-				rec += ", %s" % p
-			print rec
+        semanage_port_key_free(k)
+
+    def delete(self, port, proto):
+        self.begin()
+        self.__delete(port, proto)
+        self.commit()
+
+    def get_all(self, locallist=0):
+        ddict = {}
+        if locallist:
+            (rc, self.plist) = semanage_port_list_local(self.sh)
+        else:
+            (rc, self.plist) = semanage_port_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list ports"))
+
+        for port in self.plist:
+            con = semanage_port_get_con(port)
+            ctype = semanage_context_get_type(con)
+            if ctype == "reserved_port_t":
+                continue
+            level = semanage_context_get_mls(con)
+            proto = semanage_port_get_proto(port)
+            proto_str = semanage_port_get_proto_str(proto)
+            low = semanage_port_get_low(port)
+            high = semanage_port_get_high(port)
+            ddict[(low, high, proto_str)] = (ctype, level)
+        return ddict
+
+    def get_all_by_type(self, locallist=0):
+        ddict = {}
+        if locallist:
+            (rc, self.plist) = semanage_port_list_local(self.sh)
+        else:
+            (rc, self.plist) = semanage_port_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list ports"))
+
+        for port in self.plist:
+            con = semanage_port_get_con(port)
+            ctype = semanage_context_get_type(con)
+            if ctype == "reserved_port_t":
+                continue
+            proto = semanage_port_get_proto(port)
+            proto_str = semanage_port_get_proto_str(proto)
+            low = semanage_port_get_low(port)
+            high = semanage_port_get_high(port)
+            if (ctype, proto_str) not in ddict.keys():
+                ddict[(ctype, proto_str)] = []
+            if low == high:
+                ddict[(ctype, proto_str)].append("%d" % low)
+            else:
+                ddict[(ctype, proto_str)].append("%d-%d" % (low, high))
+        return ddict
+
+    def customized(self):
+        l = []
+        ddict = self.get_all(True)
+        keys = ddict.keys()
+        keys.sort()
+        for k in keys:
+            if k[0] == k[1]:
+                l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0]))
+            else:
+                l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1]))
+        return l
+
+    def list(self, heading=1, locallist=0):
+        ddict = self.get_all_by_type(locallist)
+        keys = ddict.keys()
+        if len(keys) == 0:
+            return
+        keys.sort()
+
+        if heading:
+            print "%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))
+        for i in keys:
+            rec = "%-30s %-8s " % i
+            rec += "%s" % ddict[i][0]
+            for p in ddict[i][1:]:
+                rec += ", %s" % p
+            print rec
+
 
 class nodeRecords(semanageRecords):
-       try:
-	       valid_types =  sepolicy.info(sepolicy.ATTRIBUTE,"node_type")[0]["types"]
-       except RuntimeError:
-	       valid_types = []
+    try:
+        valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "node_type")[0]["types"]
+    except RuntimeError:
+        valid_types = []
 
-       def __init__(self, store = ""):
-               semanageRecords.__init__(self,store)
-               self.protocol = ["ipv4", "ipv6"]
+    def __init__(self, store=""):
+        semanageRecords.__init__(self, store)
+        self.protocol = ["ipv4", "ipv6"]
 
-       def validate(self, addr, mask, protocol):
-               newaddr=addr
-               newmask=mask
-               newprotocol=""
+    def validate(self, addr, mask, protocol):
+        newaddr = addr
+        newmask = mask
+        newprotocol = ""
 
-               if addr == "":
-                       raise ValueError(_("Node Address is required"))
+        if addr == "":
+            raise ValueError(_("Node Address is required"))
 
-               # verify valid comination
-               if len(mask) == 0 or mask[0] == "/":
-                       i = IP(addr + mask)
-                       newaddr = i.strNormal(0)
-                       newmask = str(i.netmask())
-                       if newmask == "0.0.0.0" and i.version() == 6:
-                               newmask = "::"
+        # verify valid comination
+        if len(mask) == 0 or mask[0] == "/":
+            i = IP(addr + mask)
+            newaddr = i.strNormal(0)
+            newmask = str(i.netmask())
+            if newmask == "0.0.0.0" and i.version() == 6:
+                newmask = "::"
 
-                       protocol = "ipv%d" % i.version()
+            protocol = "ipv%d" % i.version()
 
-               try:
-                      newprotocol = self.protocol.index(protocol)
-               except:
-                      raise ValueError(_("Unknown or missing protocol"))
+        try:
+            newprotocol = self.protocol.index(protocol)
+        except:
+            raise ValueError(_("Unknown or missing protocol"))
 
-               return newaddr, newmask, newprotocol
+        return newaddr, newmask, newprotocol
 
-       def __add(self, addr, mask, proto, serange, ctype):
-               addr, mask, proto = self.validate(addr, mask, proto)
+    def __add(self, addr, mask, proto, serange, ctype):
+        addr, mask, proto = self.validate(addr, mask, proto)
 
-               if is_mls_enabled == 1:
-                       if serange == "":
-                               serange = "s0"
-                       else:
-                               serange = untranslate(serange)
+        if is_mls_enabled == 1:
+            if serange == "":
+                serange = "s0"
+            else:
+                serange = untranslate(serange)
 
-               if ctype == "":
-                       raise ValueError(_("SELinux node type is required"))
+        if ctype == "":
+            raise ValueError(_("SELinux node type is required"))
 
-	       if ctype not in self.valid_types:
-		       raise ValueError(_("Type %s is invalid, must be a node type") % ctype)
+        if ctype not in self.valid_types:
+            raise ValueError(_("Type %s is invalid, must be a node type") % ctype)
 
-               (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
-               if rc < 0:
-                       raise ValueError(_("Could not create key for %s") % addr)
-               if rc < 0:
-                       raise ValueError(_("Could not check if addr %s is defined") % addr)
+        (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
+        if rc < 0:
+            raise ValueError(_("Could not create key for %s") % addr)
+        if rc < 0:
+            raise ValueError(_("Could not check if addr %s is defined") % addr)
 
-               (rc, exists) = semanage_node_exists(self.sh, k)
-               if exists:
-                       raise ValueError(_("Addr %s already defined") % addr)
+        (rc, exists) = semanage_node_exists(self.sh, k)
+        if exists:
+            raise ValueError(_("Addr %s already defined") % addr)
 
-               (rc, node) = semanage_node_create(self.sh)
-               if rc < 0:
-                       raise ValueError(_("Could not create addr for %s") % addr)
-               semanage_node_set_proto(node, proto)
+        (rc, node) = semanage_node_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create addr for %s") % addr)
+        semanage_node_set_proto(node, proto)
 
-               rc = semanage_node_set_addr(self.sh, node, proto, addr)
-               (rc, con) = semanage_context_create(self.sh)
-               if rc < 0:
-                       raise ValueError(_("Could not create context for %s") % addr)
+        rc = semanage_node_set_addr(self.sh, node, proto, addr)
+        (rc, con) = semanage_context_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create context for %s") % addr)
 
-               rc = semanage_node_set_mask(self.sh, node, proto, mask)
-               if rc < 0:
-                       raise ValueError(_("Could not set mask for %s") % addr)
+        rc = semanage_node_set_mask(self.sh, node, proto, mask)
+        if rc < 0:
+            raise ValueError(_("Could not set mask for %s") % addr)
 
-               rc = semanage_context_set_user(self.sh, con, "system_u")
-               if rc < 0:
-                       raise ValueError(_("Could not set user in addr context for %s") % addr)
+        rc = semanage_context_set_user(self.sh, con, "system_u")
+        if rc < 0:
+            raise ValueError(_("Could not set user in addr context for %s") % addr)
 
-               rc = semanage_context_set_role(self.sh, con, "object_r")
-               if rc < 0:
-                       raise ValueError(_("Could not set role in addr context for %s") % addr)
+        rc = semanage_context_set_role(self.sh, con, "object_r")
+        if rc < 0:
+            raise ValueError(_("Could not set role in addr context for %s") % addr)
 
-               rc = semanage_context_set_type(self.sh, con, ctype)
-               if rc < 0:
-                       raise ValueError(_("Could not set type in addr context for %s") % addr)
+        rc = semanage_context_set_type(self.sh, con, ctype)
+        if rc < 0:
+            raise ValueError(_("Could not set type in addr context for %s") % addr)
 
-               if (is_mls_enabled == 1) and (serange != ""):
-                       rc = semanage_context_set_mls(self.sh, con, serange)
-                       if rc < 0:
-                               raise ValueError(_("Could not set mls fields in addr context for %s") % addr)
+        if (is_mls_enabled == 1) and (serange != ""):
+            rc = semanage_context_set_mls(self.sh, con, serange)
+            if rc < 0:
+                raise ValueError(_("Could not set mls fields in addr context for %s") % addr)
 
-               rc = semanage_node_set_con(self.sh, node, con)
-               if rc < 0:
-                       raise ValueError(_("Could not set addr context for %s") % addr)
+        rc = semanage_node_set_con(self.sh, node, con)
+        if rc < 0:
+            raise ValueError(_("Could not set addr context for %s") % addr)
 
-               rc = semanage_node_modify_local(self.sh, k, node)
-               if rc < 0:
-                       raise ValueError(_("Could not add addr %s") % addr)
+        rc = semanage_node_modify_local(self.sh, k, node)
+        if rc < 0:
+            raise ValueError(_("Could not add addr %s") % addr)
 
-               semanage_context_free(con)
-               semanage_node_key_free(k)
-               semanage_node_free(node)
+        semanage_context_free(con)
+        semanage_node_key_free(k)
+        semanage_node_free(node)
 
-       def add(self, addr, mask, proto, serange, ctype):
-                self.begin()
-                self.__add(addr, mask, proto, serange, ctype)
-                self.commit()
+    def add(self, addr, mask, proto, serange, ctype):
+        self.begin()
+        self.__add(addr, mask, proto, serange, ctype)
+        self.commit()
 
-       def __modify(self, addr, mask, proto, serange, setype):
-               addr, mask, proto = self.validate(addr, mask, proto)
+    def __modify(self, addr, mask, proto, serange, setype):
+        addr, mask, proto = self.validate(addr, mask, proto)
 
-               if serange == "" and setype == "":
-                       raise ValueError(_("Requires setype or serange"))
+        if serange == "" and setype == "":
+            raise ValueError(_("Requires setype or serange"))
 
-	       if setype and setype not in self.valid_types:
-		       raise ValueError(_("Type %s is invalid, must be a node type") % setype)
+        if setype and setype not in self.valid_types:
+            raise ValueError(_("Type %s is invalid, must be a node type") % setype)
 
-               (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
-               if rc < 0:
-                       raise ValueError(_("Could not create key for %s") % addr)
+        (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
+        if rc < 0:
+            raise ValueError(_("Could not create key for %s") % addr)
 
-               (rc, exists) = semanage_node_exists(self.sh, k)
-               if rc < 0:
-                       raise ValueError(_("Could not check if addr %s is defined") % addr)
-               if not exists:
-                       raise ValueError(_("Addr %s is not defined") % addr)
+        (rc, exists) = semanage_node_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if addr %s is defined") % addr)
+        if not exists:
+            raise ValueError(_("Addr %s is not defined") % addr)
 
-               (rc, node) = semanage_node_query(self.sh, k)
-               if rc < 0:
-                       raise ValueError(_("Could not query addr %s") % addr)
+        (rc, node) = semanage_node_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query addr %s") % addr)
 
-               con = semanage_node_get_con(node)
-               if (is_mls_enabled == 1) and (serange != ""):
-                       semanage_context_set_mls(self.sh, con, untranslate(serange))
-               if setype != "":
-                       semanage_context_set_type(self.sh, con, setype)
+        con = semanage_node_get_con(node)
+        if (is_mls_enabled == 1) and (serange != ""):
+            semanage_context_set_mls(self.sh, con, untranslate(serange))
+        if setype != "":
+            semanage_context_set_type(self.sh, con, setype)
 
-               rc = semanage_node_modify_local(self.sh, k, node)
-               if rc < 0:
-                       raise ValueError(_("Could not modify addr %s") % addr)
+        rc = semanage_node_modify_local(self.sh, k, node)
+        if rc < 0:
+            raise ValueError(_("Could not modify addr %s") % addr)
 
-               semanage_node_key_free(k)
-               semanage_node_free(node)
+        semanage_node_key_free(k)
+        semanage_node_free(node)
 
-       def modify(self, addr, mask, proto, serange, setype):
-                self.begin()
-                self.__modify(addr, mask, proto, serange, setype)
-                self.commit()
+    def modify(self, addr, mask, proto, serange, setype):
+        self.begin()
+        self.__modify(addr, mask, proto, serange, setype)
+        self.commit()
 
-       def __delete(self, addr, mask, proto):
+    def __delete(self, addr, mask, proto):
 
-               addr, mask, proto = self.validate(addr, mask, proto)
+        addr, mask, proto = self.validate(addr, mask, proto)
 
-               (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
-               if rc < 0:
-                       raise ValueError(_("Could not create key for %s") % addr)
+        (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
+        if rc < 0:
+            raise ValueError(_("Could not create key for %s") % addr)
 
-               (rc, exists) = semanage_node_exists(self.sh, k)
-               if rc < 0:
-                       raise ValueError(_("Could not check if addr %s is defined") % addr)
-               if not exists:
-                       raise ValueError(_("Addr %s is not defined") % addr)
+        (rc, exists) = semanage_node_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if addr %s is defined") % addr)
+        if not exists:
+            raise ValueError(_("Addr %s is not defined") % addr)
 
-               (rc, exists) = semanage_node_exists_local(self.sh, k)
-               if rc < 0:
-                       raise ValueError(_("Could not check if addr %s is defined") % addr)
-               if not exists:
-                       raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr)
+        (rc, exists) = semanage_node_exists_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if addr %s is defined") % addr)
+        if not exists:
+            raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr)
 
-               rc = semanage_node_del_local(self.sh, k)
-               if rc < 0:
-                       raise ValueError(_("Could not delete addr %s") % addr)
+        rc = semanage_node_del_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not delete addr %s") % addr)
 
-               semanage_node_key_free(k)
+        semanage_node_key_free(k)
 
-       def delete(self, addr, mask, proto):
-              self.begin()
-              self.__delete(addr, mask, proto)
-              self.commit()
-		
-       def deleteall(self):
-              (rc, nlist) = semanage_node_list_local(self.sh)
-              if rc < 0:
-                     raise ValueError(_("Could not deleteall node mappings"))
+    def delete(self, addr, mask, proto):
+        self.begin()
+        self.__delete(addr, mask, proto)
+        self.commit()
 
-              self.begin()
-              for node in nlist:
-                     self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)])
-              self.commit()
+    def deleteall(self):
+        (rc, nlist) = semanage_node_list_local(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not deleteall node mappings"))
 
-       def get_all(self, locallist = 0):
-               ddict = {}
-	       if locallist :
-			(rc, self.ilist) = semanage_node_list_local(self.sh)
-	       else:
-	                (rc, self.ilist) = semanage_node_list(self.sh)
-               if rc < 0:
-                       raise ValueError(_("Could not list addrs"))
+        self.begin()
+        for node in nlist:
+            self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)])
+        self.commit()
 
-               for node in self.ilist:
-                       con = semanage_node_get_con(node)
-                       addr = semanage_node_get_addr(self.sh, node)
-                       mask = semanage_node_get_mask(self.sh, node)
-                       proto = self.protocol[semanage_node_get_proto(node)]
-                       ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
+    def get_all(self, locallist=0):
+        ddict = {}
+        if locallist:
+            (rc, self.ilist) = semanage_node_list_local(self.sh)
+        else:
+            (rc, self.ilist) = semanage_node_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list addrs"))
 
-               return ddict
+        for node in self.ilist:
+            con = semanage_node_get_con(node)
+            addr = semanage_node_get_addr(self.sh, node)
+            mask = semanage_node_get_mask(self.sh, node)
+            proto = self.protocol[semanage_node_get_proto(node)]
+            ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
 
-       def customized(self):
-               l = []
-               ddict = self.get_all(True)
-               keys = ddict.keys()
-               keys.sort()
-               for k in keys:
-                      l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2],ddict[k][2], k[0]))
-               return l
+        return ddict
 
-       def list(self, heading = 1, locallist = 0):
-               ddict = self.get_all(locallist)
-               keys = ddict.keys()
-	       if len(keys) == 0:
-		       return 
-               keys.sort()
+    def customized(self):
+        l = []
+        ddict = self.get_all(True)
+        keys = ddict.keys()
+        keys.sort()
+        for k in keys:
+            l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2], ddict[k][2], k[0]))
+        return l
 
-               if heading:
-                       print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")
-               if is_mls_enabled:
-			for k in keys:
-				val = ''
-				for fields in k:
-					val = val + '\t' + str(fields)
-                                print "%-18s %-18s %-5s %s:%s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))
-               else:
-                       for k in keys:
-                               print "%-18s %-18s %-5s %s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2])
+    def list(self, heading=1, locallist=0):
+        ddict = self.get_all(locallist)
+        keys = ddict.keys()
+        if len(keys) == 0:
+            return
+        keys.sort()
+
+        if heading:
+            print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")
+        if is_mls_enabled:
+            for k in keys:
+                val = ''
+                for fields in k:
+                    val = val + '\t' + str(fields)
+                print "%-18s %-18s %-5s %s:%s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False))
+        else:
+            for k in keys:
+                print "%-18s %-18s %-5s %s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2])
 
 
 class interfaceRecords(semanageRecords):
-	def __init__(self, store = ""):
-		semanageRecords.__init__(self, store)
 
-	def __add(self, interface, serange, ctype):
-		if is_mls_enabled == 1:
-			if serange == "":
-				serange = "s0"
-			else:
-				serange = untranslate(serange)
-			
-		if ctype == "":
-			raise ValueError(_("SELinux Type is required"))
+    def __init__(self, store=""):
+        semanageRecords.__init__(self, store)
 
-		(rc, k) = semanage_iface_key_create(self.sh, interface)
-		if rc < 0:
-			raise ValueError(_("Could not create key for %s") % interface)
+    def __add(self, interface, serange, ctype):
+        if is_mls_enabled == 1:
+            if serange == "":
+                serange = "s0"
+            else:
+                serange = untranslate(serange)
 
-		(rc, exists) = semanage_iface_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if interface %s is defined") % interface)
-		if exists:
-			raise ValueError(_("Interface %s already defined") % interface)
+        if ctype == "":
+            raise ValueError(_("SELinux Type is required"))
 
-		(rc, iface) = semanage_iface_create(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not create interface for %s") % interface)
-		
-		rc = semanage_iface_set_name(self.sh, iface, interface)
-		(rc, con) = semanage_context_create(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not create context for %s") % interface)
+        (rc, k) = semanage_iface_key_create(self.sh, interface)
+        if rc < 0:
+            raise ValueError(_("Could not create key for %s") % interface)
 
-		rc = semanage_context_set_user(self.sh, con, "system_u")
-		if rc < 0:
-			raise ValueError(_("Could not set user in interface context for %s") % interface)
+        (rc, exists) = semanage_iface_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if interface %s is defined") % interface)
+        if exists:
+            raise ValueError(_("Interface %s already defined") % interface)
 
-		rc = semanage_context_set_role(self.sh, con, "object_r")
-		if rc < 0:
-			raise ValueError(_("Could not set role in interface context for %s") % interface)
+        (rc, iface) = semanage_iface_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create interface for %s") % interface)
 
-		rc = semanage_context_set_type(self.sh, con, ctype)
-		if rc < 0:
-			raise ValueError(_("Could not set type in interface context for %s") % interface)
+        rc = semanage_iface_set_name(self.sh, iface, interface)
+        (rc, con) = semanage_context_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create context for %s") % interface)
 
-		if (is_mls_enabled == 1) and (serange != ""):
-			rc = semanage_context_set_mls(self.sh, con, serange)
-			if rc < 0:
-				raise ValueError(_("Could not set mls fields in interface context for %s") % interface)
+        rc = semanage_context_set_user(self.sh, con, "system_u")
+        if rc < 0:
+            raise ValueError(_("Could not set user in interface context for %s") % interface)
 
-		rc = semanage_iface_set_ifcon(self.sh, iface, con)
-		if rc < 0:
-			raise ValueError(_("Could not set interface context for %s") % interface)
+        rc = semanage_context_set_role(self.sh, con, "object_r")
+        if rc < 0:
+            raise ValueError(_("Could not set role in interface context for %s") % interface)
 
-		rc = semanage_iface_set_msgcon(self.sh, iface, con)
-		if rc < 0:
-			raise ValueError(_("Could not set message context for %s") % interface)
+        rc = semanage_context_set_type(self.sh, con, ctype)
+        if rc < 0:
+            raise ValueError(_("Could not set type in interface context for %s") % interface)
 
-		rc = semanage_iface_modify_local(self.sh, k, iface)
-		if rc < 0:
-			raise ValueError(_("Could not add interface %s") % interface)
+        if (is_mls_enabled == 1) and (serange != ""):
+            rc = semanage_context_set_mls(self.sh, con, serange)
+            if rc < 0:
+                raise ValueError(_("Could not set mls fields in interface context for %s") % interface)
 
-		semanage_context_free(con)
-		semanage_iface_key_free(k)
-		semanage_iface_free(iface)
+        rc = semanage_iface_set_ifcon(self.sh, iface, con)
+        if rc < 0:
+            raise ValueError(_("Could not set interface context for %s") % interface)
 
-	def add(self, interface, serange, ctype):
-                self.begin()
-                self.__add(interface, serange, ctype)
-                self.commit()
+        rc = semanage_iface_set_msgcon(self.sh, iface, con)
+        if rc < 0:
+            raise ValueError(_("Could not set message context for %s") % interface)
 
-	def __modify(self, interface, serange, setype):
-		if serange == "" and setype == "":
-			raise ValueError(_("Requires setype or serange"))
+        rc = semanage_iface_modify_local(self.sh, k, iface)
+        if rc < 0:
+            raise ValueError(_("Could not add interface %s") % interface)
 
-		(rc, k) = semanage_iface_key_create(self.sh, interface)
-		if rc < 0:
-			raise ValueError(_("Could not create key for %s") % interface)
+        semanage_context_free(con)
+        semanage_iface_key_free(k)
+        semanage_iface_free(iface)
 
-		(rc, exists) = semanage_iface_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if interface %s is defined") % interface)
-		if not exists:
-			raise ValueError(_("Interface %s is not defined") % interface)
-	
-		(rc, iface) = semanage_iface_query(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not query interface %s") % interface)
+    def add(self, interface, serange, ctype):
+        self.begin()
+        self.__add(interface, serange, ctype)
+        self.commit()
 
-		con = semanage_iface_get_ifcon(iface)
-			
-		if (is_mls_enabled == 1) and (serange != ""):
-			semanage_context_set_mls(self.sh, con, untranslate(serange))
-		if setype != "":
-			semanage_context_set_type(self.sh, con, setype)
+    def __modify(self, interface, serange, setype):
+        if serange == "" and setype == "":
+            raise ValueError(_("Requires setype or serange"))
 
-		rc = semanage_iface_modify_local(self.sh, k, iface)
-		if rc < 0:
-			raise ValueError(_("Could not modify interface %s") % interface)
-		
-		semanage_iface_key_free(k)
-		semanage_iface_free(iface)
+        (rc, k) = semanage_iface_key_create(self.sh, interface)
+        if rc < 0:
+            raise ValueError(_("Could not create key for %s") % interface)
 
-	def modify(self, interface, serange, setype):
-                self.begin()
-                self.__modify(interface, serange, setype)
-                self.commit()
+        (rc, exists) = semanage_iface_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if interface %s is defined") % interface)
+        if not exists:
+            raise ValueError(_("Interface %s is not defined") % interface)
 
-	def __delete(self, interface):
-		(rc, k) = semanage_iface_key_create(self.sh, interface)
-		if rc < 0:
-			raise ValueError(_("Could not create key for %s") % interface)
+        (rc, iface) = semanage_iface_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query interface %s") % interface)
 
-		(rc, exists) = semanage_iface_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if interface %s is defined") % interface)
-		if not exists:
-			raise ValueError(_("Interface %s is not defined") % interface)
+        con = semanage_iface_get_ifcon(iface)
 
-		(rc, exists) = semanage_iface_exists_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if interface %s is defined") % interface)
-		if not exists:
-			raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface)
+        if (is_mls_enabled == 1) and (serange != ""):
+            semanage_context_set_mls(self.sh, con, untranslate(serange))
+        if setype != "":
+            semanage_context_set_type(self.sh, con, setype)
 
-		rc = semanage_iface_del_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not delete interface %s") % interface)
+        rc = semanage_iface_modify_local(self.sh, k, iface)
+        if rc < 0:
+            raise ValueError(_("Could not modify interface %s") % interface)
 
-		semanage_iface_key_free(k)
+        semanage_iface_key_free(k)
+        semanage_iface_free(iface)
 
-	def delete(self, interface):
-                self.begin()
-                self.__delete(interface)
-                self.commit()
-		
-        def deleteall(self):
-		(rc, ulist) = semanage_iface_list_local(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not delete all interface  mappings"))
+    def modify(self, interface, serange, setype):
+        self.begin()
+        self.__modify(interface, serange, setype)
+        self.commit()
 
-                self.begin()
-		for i in ulist:
-			self.__delete(semanage_iface_get_name(i))
-                self.commit()
+    def __delete(self, interface):
+        (rc, k) = semanage_iface_key_create(self.sh, interface)
+        if rc < 0:
+            raise ValueError(_("Could not create key for %s") % interface)
 
-	def get_all(self, locallist = 0):
-		ddict = {}
-                if locallist:
-                       (rc, self.ilist) = semanage_iface_list_local(self.sh)
-                else:
-                       (rc, self.ilist) = semanage_iface_list(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list interfaces"))
+        (rc, exists) = semanage_iface_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if interface %s is defined") % interface)
+        if not exists:
+            raise ValueError(_("Interface %s is not defined") % interface)
 
-		for interface in self.ilist:
-			con = semanage_iface_get_ifcon(interface)
-			ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
+        (rc, exists) = semanage_iface_exists_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if interface %s is defined") % interface)
+        if not exists:
+            raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface)
 
-		return ddict
-			
-        def customized(self):
-                l = []
-                ddict = self.get_all(True)
-                keys = ddict.keys()
-                keys.sort()
-                for k in keys:
-                       l.append("-a -t %s %s" % (ddict[k][2], k))
-                return l
+        rc = semanage_iface_del_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not delete interface %s") % interface)
 
-	def list(self, heading = 1, locallist = 0):
-		ddict = self.get_all(locallist)
-		keys = ddict.keys()
-		if len(keys) == 0:
-			return 
-		keys.sort()
+        semanage_iface_key_free(k)
 
-		if heading:
-			print "%-30s %s\n" % (_("SELinux Interface"), _("Context"))
-		if is_mls_enabled:
-			for k in keys:
-				print "%-30s %s:%s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))
-		else:
-			for k in keys:
-				print "%-30s %s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2])
-			
+    def delete(self, interface):
+        self.begin()
+        self.__delete(interface)
+        self.commit()
+
+    def deleteall(self):
+        (rc, ulist) = semanage_iface_list_local(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not delete all interface  mappings"))
+
+        self.begin()
+        for i in ulist:
+            self.__delete(semanage_iface_get_name(i))
+        self.commit()
+
+    def get_all(self, locallist=0):
+        ddict = {}
+        if locallist:
+            (rc, self.ilist) = semanage_iface_list_local(self.sh)
+        else:
+            (rc, self.ilist) = semanage_iface_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list interfaces"))
+
+        for interface in self.ilist:
+            con = semanage_iface_get_ifcon(interface)
+            ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
+
+        return ddict
+
+    def customized(self):
+        l = []
+        ddict = self.get_all(True)
+        keys = ddict.keys()
+        keys.sort()
+        for k in keys:
+            l.append("-a -t %s %s" % (ddict[k][2], k))
+        return l
+
+    def list(self, heading=1, locallist=0):
+        ddict = self.get_all(locallist)
+        keys = ddict.keys()
+        if len(keys) == 0:
+            return
+        keys.sort()
+
+        if heading:
+            print "%-30s %s\n" % (_("SELinux Interface"), _("Context"))
+        if is_mls_enabled:
+            for k in keys:
+                print "%-30s %s:%s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False))
+        else:
+            for k in keys:
+                print "%-30s %s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2])
+
+
 class fcontextRecords(semanageRecords):
-	try:
-		valid_types =  sepolicy.info(sepolicy.ATTRIBUTE,"file_type")[0]["types"]
-		valid_types +=  sepolicy.info(sepolicy.ATTRIBUTE,"device_node")[0]["types"]
-                valid_types.append("<<none>>")
-	except RuntimeError:
-		valid_types = []
+    try:
+        valid_types = sepolicy.info(sepolicy.ATTRIBUTE, "file_type")[0]["types"]
+        valid_types += sepolicy.info(sepolicy.ATTRIBUTE, "device_node")[0]["types"]
+        valid_types.append("<<none>>")
+    except RuntimeError:
+        valid_types = []
 
-	def __init__(self, store = ""):
-		semanageRecords.__init__(self, store)
-                self.equiv = {}
-                self.equiv_dist = {}
-                self.equal_ind = False
-                try:
-                       fd = open(selinux.selinux_file_context_subs_path(), "r")
-                       for i in fd.readlines():
-                              i = i.strip()
-                              if len(i) == 0:
-                                     continue
-                              if i.startswith("#"):
-                                     continue
-                              target, substitute = i.split()
-                              self.equiv[target] = substitute
-                       fd.close()
-                except IOError:
-                       pass
-                try:
-                       fd = open(selinux.selinux_file_context_subs_dist_path(), "r")
-                       for i in fd.readlines():
-                              i = i.strip()
-                              if len(i) == 0:
-                                     continue
-                              if i.startswith("#"):
-                                     continue
-                              target, substitute = i.split()
-                              self.equiv_dist[target] = substitute
-                       fd.close()
-                except IOError:
-                       pass
-
-        def commit(self):
-                if self.equal_ind:
-                       subs_file = selinux.selinux_file_context_subs_path()
-                       tmpfile = "%s.tmp" % subs_file
-                       fd = open(tmpfile, "w")
-                       for target in self.equiv.keys():
-                              fd.write("%s %s\n" % (target, self.equiv[target]))
-                       fd.close()
-                       try:
-                              os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE])
-                       except:
-                              pass
-                       os.rename(tmpfile,subs_file)
-                       self.equal_ind = False
-		semanageRecords.commit(self)
-
-        def add_equal(self, target, substitute):
-                self.begin()
-                if target != "/" and target[-1] == "/":
-                        raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target )
-
-                if substitute != "/" and substitute[-1] == "/":
-                       raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute )
-
-                if target in self.equiv.keys():
-                       raise ValueError(_("Equivalence class for %s already exists") % target)
-                self.validate(target)
-
-		for fdict in (self.equiv, self.equiv_dist):
-			for i in fdict:
-				if i.startswith(target + "/"):
-					raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
-
+    def __init__(self, store=""):
+        semanageRecords.__init__(self, store)
+        self.equiv = {}
+        self.equiv_dist = {}
+        self.equal_ind = False
+        try:
+            fd = open(selinux.selinux_file_context_subs_path(), "r")
+            for i in fd.readlines():
+                i = i.strip()
+                if len(i) == 0:
+                    continue
+                if i.startswith("#"):
+                    continue
+                target, substitute = i.split()
                 self.equiv[target] = substitute
-                self.equal_ind = True
-                self.commit()
+            fd.close()
+        except IOError:
+            pass
+        try:
+            fd = open(selinux.selinux_file_context_subs_dist_path(), "r")
+            for i in fd.readlines():
+                i = i.strip()
+                if len(i) == 0:
+                    continue
+                if i.startswith("#"):
+                    continue
+                target, substitute = i.split()
+                self.equiv_dist[target] = substitute
+            fd.close()
+        except IOError:
+            pass
 
-        def modify_equal(self, target, substitute):
-                self.begin()
-                if target not in self.equiv.keys():
-                       raise ValueError(_("Equivalence class for %s does not exists") % target)
-                self.equiv[target] = substitute
-                self.equal_ind = True
-                self.commit()
+    def commit(self):
+        if self.equal_ind:
+            subs_file = selinux.selinux_file_context_subs_path()
+            tmpfile = "%s.tmp" % subs_file
+            fd = open(tmpfile, "w")
+            for target in self.equiv.keys():
+                fd.write("%s %s\n" % (target, self.equiv[target]))
+            fd.close()
+            try:
+                os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE])
+            except:
+                pass
+            os.rename(tmpfile, subs_file)
+            self.equal_ind = False
+        semanageRecords.commit(self)
 
-        def createcon(self, target, seuser = "system_u"):
-                (rc, con) = semanage_context_create(self.sh)
+    def add_equal(self, target, substitute):
+        self.begin()
+        if target != "/" and target[-1] == "/":
+            raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target)
+
+        if substitute != "/" and substitute[-1] == "/":
+            raise ValueError(_("Substiture %s is not valid. Substitute is not allowed to end with '/'") % substitute)
+
+        if target in self.equiv.keys():
+            raise ValueError(_("Equivalence class for %s already exists") % target)
+        self.validate(target)
+
+        for fdict in (self.equiv, self.equiv_dist):
+            for i in fdict:
+                if i.startswith(target + "/"):
+                    raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
+
+        self.equiv[target] = substitute
+        self.equal_ind = True
+        self.commit()
+
+    def modify_equal(self, target, substitute):
+        self.begin()
+        if target not in self.equiv.keys():
+            raise ValueError(_("Equivalence class for %s does not exists") % target)
+        self.equiv[target] = substitute
+        self.equal_ind = True
+        self.commit()
+
+    def createcon(self, target, seuser="system_u"):
+        (rc, con) = semanage_context_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create context for %s") % target)
+        if seuser == "":
+            seuser = "system_u"
+
+        rc = semanage_context_set_user(self.sh, con, seuser)
+        if rc < 0:
+            raise ValueError(_("Could not set user in file context for %s") % target)
+
+        rc = semanage_context_set_role(self.sh, con, "object_r")
+        if rc < 0:
+            raise ValueError(_("Could not set role in file context for %s") % target)
+
+        if is_mls_enabled == 1:
+            rc = semanage_context_set_mls(self.sh, con, "s0")
+            if rc < 0:
+                raise ValueError(_("Could not set mls fields in file context for %s") % target)
+
+        return con
+
+    def validate(self, target):
+        if target == "" or target.find("\n") >= 0:
+            raise ValueError(_("Invalid file specification"))
+        if target.find(" ") != -1:
+            raise ValueError(_("File specification can not include spaces"))
+        for fdict in (self.equiv, self.equiv_dist):
+            for i in fdict:
+                if target.startswith(i + "/"):
+                    t = re.sub(i, fdict[i], target)
+                    raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t))
+
+    def __add(self, target, type, ftype="", serange="", seuser="system_u"):
+        self.validate(target)
+
+        if is_mls_enabled == 1:
+            serange = untranslate(serange)
+
+        if type == "":
+            raise ValueError(_("SELinux Type is required"))
+
+        if type not in self.valid_types:
+            raise ValueError(_("Type %s is invalid, must be a file or device type") % type)
+
+        (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
+        if rc < 0:
+            raise ValueError(_("Could not create key for %s") % target)
+
+        (rc, exists) = semanage_fcontext_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if file context for %s is defined") % target)
+
+        if not exists:
+            (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
+            if rc < 0:
+                raise ValueError(_("Could not check if file context for %s is defined") % target)
+
+        if exists:
+            raise ValueError(_("File context for %s already defined") % target)
+
+        (rc, fcontext) = semanage_fcontext_create(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not create file context for %s") % target)
+
+        rc = semanage_fcontext_set_expr(self.sh, fcontext, target)
+        if type != "<<none>>":
+            con = self.createcon(target, seuser)
+
+            rc = semanage_context_set_type(self.sh, con, type)
+            if rc < 0:
+                raise ValueError(_("Could not set type in file context for %s") % target)
+
+            if (is_mls_enabled == 1) and (serange != ""):
+                rc = semanage_context_set_mls(self.sh, con, serange)
                 if rc < 0:
-                       raise ValueError(_("Could not create context for %s") % target)
-		if seuser == "":
-			seuser = "system_u"
+                    raise ValueError(_("Could not set mls fields in file context for %s") % target)
+            rc = semanage_fcontext_set_con(self.sh, fcontext, con)
+            if rc < 0:
+                raise ValueError(_("Could not set file context for %s") % target)
 
-                rc = semanage_context_set_user(self.sh, con, seuser)
-                if rc < 0:
-                       raise ValueError(_("Could not set user in file context for %s") % target)
-		
-                rc = semanage_context_set_role(self.sh, con, "object_r")
-                if rc < 0:
-                       raise ValueError(_("Could not set role in file context for %s") % target)
+        semanage_fcontext_set_type(fcontext, file_types[ftype])
 
-		if is_mls_enabled == 1:
-                       rc = semanage_context_set_mls(self.sh, con, "s0")
-                       if rc < 0:
-                              raise ValueError(_("Could not set mls fields in file context for %s") % target)
+        rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
+        if rc < 0:
+            raise ValueError(_("Could not add file context for %s") % target)
 
-                return con
+        if type != "<<none>>":
+            semanage_context_free(con)
+        semanage_fcontext_key_free(k)
+        semanage_fcontext_free(fcontext)
 
-        def validate(self, target):
-               if target == "" or target.find("\n") >= 0:
-                      raise ValueError(_("Invalid file specification"))
-               if target.find(" ") != -1:
-                      raise ValueError(_("File specification can not include spaces"))
-	       for fdict in (self.equiv, self.equiv_dist):
-		       for i in fdict:
-			       if target.startswith(i+"/"):
-				       t = re.sub(i, fdict[i], target)
-				       raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t))
+    def add(self, target, type, ftype="", serange="", seuser="system_u"):
+        self.begin()
+        self.__add(target, type, ftype, serange, seuser)
+        self.commit()
 
+    def __modify(self, target, setype, ftype, serange, seuser):
+        if serange == "" and setype == "" and seuser == "":
+            raise ValueError(_("Requires setype, serange or seuser"))
+        if setype and setype not in self.valid_types:
+            raise ValueError(_("Type %s is invalid, must be a port type") % setype)
 
-	def __add(self, target, type, ftype = "", serange = "", seuser = "system_u"):
-                self.validate(target)
+        self.validate(target)
 
-		if is_mls_enabled == 1:
-                       serange = untranslate(serange)
-			
-		if type == "":
-			raise ValueError(_("SELinux Type is required"))
+        (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % target)
 
-		if type not in self.valid_types:
-			raise ValueError(_("Type %s is invalid, must be a file or device type") % type)
+        (rc, exists) = semanage_fcontext_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if file context for %s is defined") % target)
+        if not exists:
+            (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
+            if not exists:
+                raise ValueError(_("File context for %s is not defined") % target)
 
-		(rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
-		if rc < 0:
-			raise ValueError(_("Could not create key for %s") % target)
+        (rc, fcontext) = semanage_fcontext_query_local(self.sh, k)
+        if rc < 0:
+            (rc, fcontext) = semanage_fcontext_query(self.sh, k)
+            if rc < 0:
+                raise ValueError(_("Could not query file context for %s") % target)
 
-		(rc, exists) = semanage_fcontext_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if file context for %s is defined") % target)
+        if setype != "<<none>>":
+            con = semanage_fcontext_get_con(fcontext)
 
-		if not exists:
-                       (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
-                       if rc < 0:
-                              raise ValueError(_("Could not check if file context for %s is defined") % target)
+            if con == None:
+                con = self.createcon(target)
 
-                if exists:
-                       raise ValueError(_("File context for %s already defined") % target)
+            if (is_mls_enabled == 1) and (serange != ""):
+                semanage_context_set_mls(self.sh, con, untranslate(serange))
+            if seuser != "":
+                semanage_context_set_user(self.sh, con, seuser)
 
-		(rc, fcontext) = semanage_fcontext_create(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not create file context for %s") % target)
-		
-		rc = semanage_fcontext_set_expr(self.sh, fcontext, target)
-                if type != "<<none>>":
-                       con = self.createcon(target, seuser)
+            if setype != "":
+                semanage_context_set_type(self.sh, con, setype)
 
-                       rc = semanage_context_set_type(self.sh, con, type)
-                       if rc < 0:
-                              raise ValueError(_("Could not set type in file context for %s") % target)
+            rc = semanage_fcontext_set_con(self.sh, fcontext, con)
+            if rc < 0:
+                raise ValueError(_("Could not set file context for %s") % target)
+        else:
+            rc = semanage_fcontext_set_con(self.sh, fcontext, None)
+            if rc < 0:
+                raise ValueError(_("Could not set file context for %s") % target)
 
-                       if (is_mls_enabled == 1) and (serange != ""):
-                              rc = semanage_context_set_mls(self.sh, con, serange)
-                              if rc < 0:
-                                     raise ValueError(_("Could not set mls fields in file context for %s") % target)
-                       rc = semanage_fcontext_set_con(self.sh, fcontext, con)
-                       if rc < 0:
-                              raise ValueError(_("Could not set file context for %s") % target)
+        rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
+        if rc < 0:
+            raise ValueError(_("Could not modify file context for %s") % target)
 
-		semanage_fcontext_set_type(fcontext, file_types[ftype])
+        semanage_fcontext_key_free(k)
+        semanage_fcontext_free(fcontext)
 
-		rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
-		if rc < 0:
-			raise ValueError(_("Could not add file context for %s") % target)
+    def modify(self, target, setype, ftype, serange, seuser):
+        self.begin()
+        self.__modify(target, setype, ftype, serange, seuser)
+        self.commit()
 
-                if type != "<<none>>":
-                       semanage_context_free(con)
-		semanage_fcontext_key_free(k)
-		semanage_fcontext_free(fcontext)
+    def deleteall(self):
+        (rc, flist) = semanage_fcontext_list_local(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list the file contexts"))
 
-	def add(self, target, type, ftype = "", serange = "", seuser = "system_u"):
-                self.begin()
-                self.__add(target, type, ftype, serange, seuser)
-                self.commit()
+        self.begin()
 
-	def __modify(self, target, setype, ftype, serange, seuser):
-		if serange == "" and setype == "" and seuser == "":
-			raise ValueError(_("Requires setype, serange or seuser"))
-		if setype and setype not in self.valid_types:
-			raise ValueError(_("Type %s is invalid, must be a port type") % setype)
+        for fcontext in flist:
+            target = semanage_fcontext_get_expr(fcontext)
+            ftype = semanage_fcontext_get_type(fcontext)
+            ftype_str = semanage_fcontext_get_type_str(ftype)
+            (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str])
+            if rc < 0:
+                raise ValueError(_("Could not create a key for %s") % target)
 
-                self.validate(target)
+            rc = semanage_fcontext_del_local(self.sh, k)
+            if rc < 0:
+                raise ValueError(_("Could not delete the file context %s") % target)
+            semanage_fcontext_key_free(k)
 
-		(rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
-		if rc < 0:
-			raise ValueError(_("Could not create a key for %s") % target)
+        self.equiv = {}
+        self.equal_ind = True
+        self.commit()
 
-		(rc, exists) = semanage_fcontext_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if file context for %s is defined") % target)
-		if not exists:
-                       (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
-                       if not exists:
-                              raise ValueError(_("File context for %s is not defined") % target)
-		
-		(rc, fcontext) = semanage_fcontext_query_local(self.sh, k)
-		if rc < 0:
-                       (rc, fcontext) = semanage_fcontext_query(self.sh, k)
-                       if rc < 0:
-                              raise ValueError(_("Could not query file context for %s") % target)
+    def __delete(self, target, ftype):
+        if target in self.equiv.keys():
+            self.equiv.pop(target)
+            self.equal_ind = True
+            return
 
-                if setype != "<<none>>":
-                       con = semanage_fcontext_get_con(fcontext)
-			
-                       if con == None:
-                              con = self.createcon(target)
-                              
-                       if (is_mls_enabled == 1) and (serange != ""):
-                              semanage_context_set_mls(self.sh, con, untranslate(serange))
-                       if seuser != "":
-                              semanage_context_set_user(self.sh, con, seuser)
-                              
-                       if setype != "":
-                              semanage_context_set_type(self.sh, con, setype)
+        (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % target)
 
-                       rc = semanage_fcontext_set_con(self.sh, fcontext, con)
-                       if rc < 0:
-                              raise ValueError(_("Could not set file context for %s") % target)
+        (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if file context for %s is defined") % target)
+        if not exists:
+            (rc, exists) = semanage_fcontext_exists(self.sh, k)
+            if rc < 0:
+                raise ValueError(_("Could not check if file context for %s is defined") % target)
+            if exists:
+                raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target)
+            else:
+                raise ValueError(_("File context for %s is not defined") % target)
+
+        rc = semanage_fcontext_del_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not delete file context for %s") % target)
+
+        semanage_fcontext_key_free(k)
+
+    def delete(self, target, ftype):
+        self.begin()
+        self.__delete(target, ftype)
+        self.commit()
+
+    def get_all(self, locallist=0):
+        if locallist:
+            (rc, self.flist) = semanage_fcontext_list_local(self.sh)
+        else:
+            (rc, self.flist) = semanage_fcontext_list(self.sh)
+            if rc < 0:
+                raise ValueError(_("Could not list file contexts"))
+
+            (rc, fclocal) = semanage_fcontext_list_local(self.sh)
+            if rc < 0:
+                raise ValueError(_("Could not list local file contexts"))
+
+            self.flist += fclocal
+
+        ddict = {}
+        for fcontext in self.flist:
+            expr = semanage_fcontext_get_expr(fcontext)
+            ftype = semanage_fcontext_get_type(fcontext)
+            ftype_str = semanage_fcontext_get_type_str(ftype)
+            con = semanage_fcontext_get_con(fcontext)
+            if con:
+                ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
+            else:
+                ddict[(expr, ftype_str)] = con
+
+        return ddict
+
+    def customized(self):
+        l = []
+        fcon_dict = self.get_all(True)
+        keys = fcon_dict.keys()
+        keys.sort()
+        for k in keys:
+            if fcon_dict[k]:
+                l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0]))
+
+        if len(self.equiv):
+            for target in self.equiv.keys():
+                l.append("-a -e %s %s" % (self.equiv[target], target))
+        return l
+
+    def list(self, heading=1, locallist=0):
+        fcon_dict = self.get_all(locallist)
+        keys = fcon_dict.keys()
+        if len(keys) != 0:
+            keys.sort()
+            if heading:
+                print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))
+            for k in keys:
+                if fcon_dict[k]:
+                    if is_mls_enabled:
+                        print "%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3], False))
+                    else:
+                        print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2])
                 else:
-                       rc = semanage_fcontext_set_con(self.sh, fcontext, None)
-                       if rc < 0:
-                              raise ValueError(_("Could not set file context for %s") % target)
-                       
-		rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
-		if rc < 0:
-			raise ValueError(_("Could not modify file context for %s") % target)
+                    print "%-50s %-18s <<None>>" % (k[0], k[1])
 
-		semanage_fcontext_key_free(k)
-		semanage_fcontext_free(fcontext)
+        if len(self.equiv_dist):
+            if not locallist:
+                if heading:
+                    print _("\nSELinux Distribution fcontext Equivalence \n")
+                for target in self.equiv_dist.keys():
+                    print "%s = %s" % (target, self.equiv_dist[target])
+        if len(self.equiv):
+            if heading:
+                print _("\nSELinux Local fcontext Equivalence \n")
 
-	def modify(self, target, setype, ftype, serange, seuser):
-                self.begin()
-                self.__modify(target, setype, ftype, serange, seuser)
-                self.commit()
+            for target in self.equiv.keys():
+                print "%s = %s" % (target, self.equiv[target])
 
-	def deleteall(self):
-		(rc, flist) = semanage_fcontext_list_local(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list the file contexts"))
 
-                self.begin()
-
-		for fcontext in flist:
-                       target = semanage_fcontext_get_expr(fcontext)
-                       ftype = semanage_fcontext_get_type(fcontext)
-                       ftype_str = semanage_fcontext_get_type_str(ftype)
-                       (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str])
-                       if rc < 0:
-                              raise ValueError(_("Could not create a key for %s") % target)
-
-                       rc = semanage_fcontext_del_local(self.sh, k)
-                       if rc < 0:
-                              raise ValueError(_("Could not delete the file context %s") % target)
-                       semanage_fcontext_key_free(k)
-	
-                self.equiv = {}
-                self.equal_ind = True
-                self.commit()
-
-	def __delete(self, target, ftype):
-                if target in self.equiv.keys():
-                       self.equiv.pop(target)
-                       self.equal_ind = True
-                       return
-
-		(rc,k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
-		if rc < 0:
-			raise ValueError(_("Could not create a key for %s") % target)
-
-		(rc, exists) = semanage_fcontext_exists_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if file context for %s is defined") % target)
-		if not exists:
-			(rc, exists) = semanage_fcontext_exists(self.sh, k)
-			if rc < 0:
-				raise ValueError(_("Could not check if file context for %s is defined") % target)
-			if exists:
-				raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target)
-			else:
-				raise ValueError(_("File context for %s is not defined") % target)
-
-		rc = semanage_fcontext_del_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not delete file context for %s") % target)
-
-		semanage_fcontext_key_free(k)		
-
-	def delete(self, target, ftype):
-                self.begin()
-                self.__delete( target, ftype)
-                self.commit()
-
-	def get_all(self, locallist = 0):
-                if locallist:
-                       (rc, self.flist) = semanage_fcontext_list_local(self.sh)
-                else:
-                       (rc, self.flist) = semanage_fcontext_list(self.sh)
-                       if rc < 0:
-                              raise ValueError(_("Could not list file contexts"))
-
-                       (rc, fclocal) = semanage_fcontext_list_local(self.sh)
-                       if rc < 0:
-                              raise ValueError(_("Could not list local file contexts"))
-
-                       self.flist += fclocal
-
-                ddict = {}
-		for fcontext in self.flist:
-			expr = semanage_fcontext_get_expr(fcontext)
-			ftype = semanage_fcontext_get_type(fcontext)
-			ftype_str = semanage_fcontext_get_type_str(ftype)
-			con = semanage_fcontext_get_con(fcontext)
-			if con:
-                               ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
-			else:
-				ddict[(expr, ftype_str)] = con
-
-		return ddict
-			
-        def customized(self):
-               l = []
-               fcon_dict = self.get_all(True)
-               keys = fcon_dict.keys()
-               keys.sort()
-               for k in keys:
-                      if fcon_dict[k]:
-                             l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0]))
-
-	       if len(self.equiv):
-                      for target in self.equiv.keys():
-			     l.append("-a -e %s %s" % (self.equiv[target], target))
-               return l
-
-	def list(self, heading = 1, locallist = 0 ):
-		fcon_dict = self.get_all(locallist)
-                keys = fcon_dict.keys()
-		if len(keys) != 0:
-			keys.sort()
-			if heading:
-				print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))
-			for k in keys:
-				if fcon_dict[k]:
-					if is_mls_enabled:
-						print "%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3],False))
-					else:
-						print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1],fcon_dict[k][2])
-				else:
-					print "%-50s %-18s <<None>>" % (k[0], k[1])
-
-		if len(self.equiv_dist):
-		       if not locallist:
-			       if heading:
-				       print _("\nSELinux Distribution fcontext Equivalence \n")
-			       for target in self.equiv_dist.keys():
-				       print "%s = %s" % (target, self.equiv_dist[target])
-		if len(self.equiv):
-                       if heading:
-                              print _("\nSELinux Local fcontext Equivalence \n")
-
-                       for target in self.equiv.keys():
-                              print "%s = %s" % (target, self.equiv[target])
-				
 class booleanRecords(semanageRecords):
-	def __init__(self, store = ""):
-		semanageRecords.__init__(self, store)
-                self.dict = {}
-                self.dict["TRUE"] = 1
-                self.dict["FALSE"] = 0
-                self.dict["ON"] = 1
-                self.dict["OFF"] = 0
-                self.dict["1"] = 1
-                self.dict["0"] = 0
 
-		try:
-			rc, self.current_booleans = selinux.security_get_boolean_names()
-			rc, ptype = selinux.selinux_getpolicytype()
-		except:
-			self.current_booleans = []
-			ptype = None
+    def __init__(self, store=""):
+        semanageRecords.__init__(self, store)
+        self.dict = {}
+        self.dict["TRUE"] = 1
+        self.dict["FALSE"] = 0
+        self.dict["ON"] = 1
+        self.dict["OFF"] = 0
+        self.dict["1"] = 1
+        self.dict["0"] = 0
 
-		if self.store == None or self.store == ptype:
-			self.modify_local = True
-		else:
-			self.modify_local = False
+        try:
+            rc, self.current_booleans = selinux.security_get_boolean_names()
+            rc, ptype = selinux.selinux_getpolicytype()
+        except:
+            self.current_booleans = []
+            ptype = None
 
-	def __mod(self, name, value):
-                name = selinux.selinux_boolean_sub(name)
+        if self.store == None or self.store == ptype:
+            self.modify_local = True
+        else:
+            self.modify_local = False
 
-                (rc, k) = semanage_bool_key_create(self.sh, name)
-                if rc < 0:
-                       raise ValueError(_("Could not create a key for %s") % name)
-                (rc, exists) = semanage_bool_exists(self.sh, k)
-                if rc < 0:
-                       raise ValueError(_("Could not check if boolean %s is defined") % name)
-                if not exists:
-                       raise ValueError(_("Boolean %s is not defined") % name)	
-                
-                (rc, b) = semanage_bool_query(self.sh, k)
-                if rc < 0:
-                       raise ValueError(_("Could not query file context %s") % name)
+    def __mod(self, name, value):
+        name = selinux.selinux_boolean_sub(name)
 
-                if value.upper() in self.dict:
-                       semanage_bool_set_value(b, self.dict[value.upper()])
-                else:
-                       raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()) )
-                
-		if self.modify_local and name in self.current_booleans:
-			rc = semanage_bool_set_active(self.sh, k, b)
-			if rc < 0:
-				raise ValueError(_("Could not set active value of boolean %s") % name)
-                rc = semanage_bool_modify_local(self.sh, k, b)
-                if rc < 0:
-                       raise ValueError(_("Could not modify boolean %s") % name)
-		semanage_bool_key_free(k)
-		semanage_bool_free(b)
+        (rc, k) = semanage_bool_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
+        (rc, exists) = semanage_bool_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if boolean %s is defined") % name)
+        if not exists:
+            raise ValueError(_("Boolean %s is not defined") % name)
 
-	def modify(self, name, value = None, use_file = False):
-                self.begin()
-                if use_file:
-                       fd = open(name)
-                       for b in fd.read().split("\n"):
-                              b = b.strip()
-                              if len(b) == 0:
-                                     continue
+        (rc, b) = semanage_bool_query(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not query file context %s") % name)
 
-                              try:
-                                     boolname, val = b.split("=")
-                              except ValueError:
-                                     raise ValueError(_("Bad format %s: Record %s" % ( name, b) ))
-                              self.__mod(boolname.strip(), val.strip())
-                       fd.close()
-                else:
-                       self.__mod(name, value)
+        if value.upper() in self.dict:
+            semanage_bool_set_value(b, self.dict[value.upper()])
+        else:
+            raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()))
 
-                self.commit()
-		
-	def __delete(self, name):
-                name = selinux.selinux_boolean_sub(name)
+        if self.modify_local and name in self.current_booleans:
+            rc = semanage_bool_set_active(self.sh, k, b)
+            if rc < 0:
+                raise ValueError(_("Could not set active value of boolean %s") % name)
+        rc = semanage_bool_modify_local(self.sh, k, b)
+        if rc < 0:
+            raise ValueError(_("Could not modify boolean %s") % name)
+        semanage_bool_key_free(k)
+        semanage_bool_free(b)
 
-                (rc, k) = semanage_bool_key_create(self.sh, name)
-                if rc < 0:
-                      raise ValueError(_("Could not create a key for %s") % name)
-		(rc, exists) = semanage_bool_exists(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if boolean %s is defined") % name)
-		if not exists:
-			raise ValueError(_("Boolean %s is not defined") % name)
-	
-		(rc, exists) = semanage_bool_exists_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not check if boolean %s is defined") % name)
-		if not exists:
-			raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name)
+    def modify(self, name, value=None, use_file=False):
+        self.begin()
+        if use_file:
+            fd = open(name)
+            for b in fd.read().split("\n"):
+                b = b.strip()
+                if len(b) == 0:
+                    continue
 
-		rc = semanage_bool_del_local(self.sh, k)
-		if rc < 0:
-			raise ValueError(_("Could not delete boolean %s") % name)
-	
-		semanage_bool_key_free(k)
+                try:
+                    boolname, val = b.split("=")
+                except ValueError:
+                    raise ValueError(_("Bad format %s: Record %s" % (name, b)))
+                self.__mod(boolname.strip(), val.strip())
+            fd.close()
+        else:
+            self.__mod(name, value)
 
-	def delete(self, name):
-                self.begin()
-                self.__delete(name)
-                self.commit()
+        self.commit()
 
-	def deleteall(self):
-		(rc, self.blist) = semanage_bool_list_local(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list booleans"))
+    def __delete(self, name):
+        name = selinux.selinux_boolean_sub(name)
 
-                self.begin()
+        (rc, k) = semanage_bool_key_create(self.sh, name)
+        if rc < 0:
+            raise ValueError(_("Could not create a key for %s") % name)
+        (rc, exists) = semanage_bool_exists(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if boolean %s is defined") % name)
+        if not exists:
+            raise ValueError(_("Boolean %s is not defined") % name)
 
-		for boolean in self.blist:
-                       name = semanage_bool_get_name(boolean)
-                       self.__delete(name)
+        (rc, exists) = semanage_bool_exists_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not check if boolean %s is defined") % name)
+        if not exists:
+            raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name)
 
-                self.commit()
-	
-	def get_all(self, locallist = 0):
-		ddict = {}
-                if locallist:
-                       (rc, self.blist) = semanage_bool_list_local(self.sh)
-                else:
-                       (rc, self.blist) = semanage_bool_list(self.sh)
-		if rc < 0:
-			raise ValueError(_("Could not list booleans"))
+        rc = semanage_bool_del_local(self.sh, k)
+        if rc < 0:
+            raise ValueError(_("Could not delete boolean %s") % name)
 
-		for boolean in self.blist:
-                       value = []
-                       name = semanage_bool_get_name(boolean)
-                       value.append(semanage_bool_get_value(boolean))
-		       if self.modify_local and boolean in self.current_booleans:
-			       value.append(selinux.security_get_boolean_pending(name))
-			       value.append(selinux.security_get_boolean_active(name))
-		       else:
-			       value.append(value[0])
-			       value.append(value[0])
-                       ddict[name] = value
+        semanage_bool_key_free(k)
 
-		return ddict
-			
-        def get_desc(self, name):
-		name = selinux.selinux_boolean_sub(name)
-		return boolean_desc(name)
+    def delete(self, name):
+        self.begin()
+        self.__delete(name)
+        self.commit()
 
-        def get_category(self, name):
-		name = selinux.selinux_boolean_sub(name)
-		return boolean_category(name)
+    def deleteall(self):
+        (rc, self.blist) = semanage_bool_list_local(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list booleans"))
 
-        def customized(self):
-               l = []
-               ddict = self.get_all(True)
-               keys = ddict.keys()
-               keys.sort()
-               for k in keys:
-                      if ddict[k]:
-                             l.append("-m -%s %s" %  (ddict[k][2], k))
-               return l
+        self.begin()
 
-	def list(self, heading = True, locallist = False, use_file = False):
-                on_off = (_("off"), _("on")) 
-		if use_file:
-                       ddict = self.get_all(locallist)
-                       keys = ddict.keys()
-                       for k in keys:
-                              if ddict[k]:
-                                     print "%s=%s" %  (k, ddict[k][2])
-                       return
-		ddict = self.get_all(locallist)
-		keys = ddict.keys()
-		if len(keys) == 0:
-			return 
+        for boolean in self.blist:
+            name = semanage_bool_get_name(boolean)
+            self.__delete(name)
 
-		if heading:
-			print "%-30s %s  %s %s\n" % (_("SELinux boolean"),_("State"), _("Default"), _("Description"))
-		for k in keys:
-			if ddict[k]:
-				print "%-30s (%-5s,%5s)  %s" %  (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k))
+        self.commit()
+
+    def get_all(self, locallist=0):
+        ddict = {}
+        if locallist:
+            (rc, self.blist) = semanage_bool_list_local(self.sh)
+        else:
+            (rc, self.blist) = semanage_bool_list(self.sh)
+        if rc < 0:
+            raise ValueError(_("Could not list booleans"))
+
+        for boolean in self.blist:
+            value = []
+            name = semanage_bool_get_name(boolean)
+            value.append(semanage_bool_get_value(boolean))
+            if self.modify_local and boolean in self.current_booleans:
+                value.append(selinux.security_get_boolean_pending(name))
+                value.append(selinux.security_get_boolean_active(name))
+            else:
+                value.append(value[0])
+                value.append(value[0])
+            ddict[name] = value
+
+        return ddict
+
+    def get_desc(self, name):
+        name = selinux.selinux_boolean_sub(name)
+        return boolean_desc(name)
+
+    def get_category(self, name):
+        name = selinux.selinux_boolean_sub(name)
+        return boolean_category(name)
+
+    def customized(self):
+        l = []
+        ddict = self.get_all(True)
+        keys = ddict.keys()
+        keys.sort()
+        for k in keys:
+            if ddict[k]:
+                l.append("-m -%s %s" % (ddict[k][2], k))
+        return l
+
+    def list(self, heading=True, locallist=False, use_file=False):
+        on_off = (_("off"), _("on"))
+        if use_file:
+            ddict = self.get_all(locallist)
+            keys = ddict.keys()
+            for k in keys:
+                if ddict[k]:
+                    print "%s=%s" % (k, ddict[k][2])
+            return
+        ddict = self.get_all(locallist)
+        keys = ddict.keys()
+        if len(keys) == 0:
+            return
+
+        if heading:
+            print "%-30s %s  %s %s\n" % (_("SELinux boolean"), _("State"), _("Default"), _("Description"))
+        for k in keys:
+            if ddict[k]:
+                print "%-30s (%-5s,%5s)  %s" % (k, on_off[selinux.security_get_boolean_active(k)], on_off[ddict[k][2]], self.get_desc(k))
diff --git a/policycoreutils/semanage/test-semanage.py b/policycoreutils/semanage/test-semanage.py
index d39013e..293e1fd 100644
--- a/policycoreutils/semanage/test-semanage.py
+++ b/policycoreutils/semanage/test-semanage.py
@@ -1,59 +1,65 @@
-import unittest, os, shutil, sys
+import unittest
+import os
+import shutil
+import sys
 from tempfile import mkdtemp
 from subprocess import Popen, PIPE
 
 import argparse
 
-object_list = [ 'login', 'user', 'port', 'module', 'interface', 'node', 'fcontext', 'boolean','permissive', "dontaudit"]
+object_list = ['login', 'user', 'port', 'module', 'interface', 'node', 'fcontext', 'boolean', 'permissive', "dontaudit"]
+
 
 class SemanageTests(unittest.TestCase):
+
     def assertDenied(self, err):
         self.assertTrue('Permission denied' in err,
-                     '"Permission denied" not found in %r' % err)
+                        '"Permission denied" not found in %r' % err)
+
     def assertNotFound(self, err):
         self.assertTrue('not found' in err,
-                     '"not found" not found in %r' % err)
+                        '"not found" not found in %r' % err)
 
     def assertFailure(self, status):
         self.assertTrue(status != 0,
-                     '"semanage succeeded when it should have failed')
+                        '"semanage succeeded when it should have failed')
 
     def assertSuccess(self, status, err):
         self.assertTrue(status == 0,
-                     '"semanage should have succeeded for this test %r' %  err)
+                        '"semanage should have succeeded for this test %r' % err)
 
     def test_extract(self):
         for object in object_list:
-            if object in ["dontaudit","module","permissive"]:
+            if object in ["dontaudit", "module", "permissive"]:
                 continue
             "Verify semanage %s -E" % object
-            p = Popen(['semanage', object, '-E'], stdout = PIPE)
+            p = Popen(['semanage', object, '-E'], stdout=PIPE)
             out, err = p.communicate()
             self.assertSuccess(p.returncode, err)
 
     def test_input_output(self):
         print("Verify semanage export -f /tmp/out")
-        p = Popen(['semanage', "export", '-f', '/tmp/out'], stdout = PIPE)
+        p = Popen(['semanage', "export", '-f', '/tmp/out'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
         print("Verify semanage export -S targeted -f -")
-        p = Popen(["semanage","export","-S","targeted","-f","-"], stdout = PIPE)
+        p = Popen(["semanage", "export", "-S", "targeted", "-f", "-"], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
         print("Verify semanage -S targeted -o -")
-        p = Popen(["semanage","-S","targeted","-o","-"], stdout = PIPE)
+        p = Popen(["semanage", "-S", "targeted", "-o", "-"], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
         print("Verify semanage import -f /tmp/out")
-        p = Popen(['semanage', "import", '-f', '/tmp/out'], stdout = PIPE)
+        p = Popen(['semanage', "import", '-f', '/tmp/out'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
         print("Verify semanage import -S targeted -f /tmp/out")
-        p = Popen(["semanage","import","-S","targeted","-f", "/tmp/out"], stdout = PIPE)
+        p = Popen(["semanage", "import", "-S", "targeted", "-f", "/tmp/out"], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
         print("Verify semanage -S targeted -i /tmp/out")
-        p = Popen(["semanage", "-S","targeted","-i", "/tmp/out"], stdout = PIPE)
+        p = Popen(["semanage", "-S", "targeted", "-i", "/tmp/out"], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
@@ -62,7 +68,7 @@
             if object in ["dontaudit"]:
                 continue
             "Verify semanage %s -l" % object
-            p = Popen(['semanage', object, '-l'], stdout = PIPE)
+            p = Popen(['semanage', object, '-l'], stdout=PIPE)
             out, err = p.communicate()
             self.assertSuccess(p.returncode, err)
 
@@ -71,165 +77,170 @@
             if object in ["module", "permissive", "dontaudit"]:
                 continue
             print("Verify semanage %s -l" % object)
-            p = Popen(['semanage', object, '-lC'], stdout = PIPE)
+            p = Popen(['semanage', object, '-lC'], stdout=PIPE)
             out, err = p.communicate()
             self.assertSuccess(p.returncode, err)
 
     def test_fcontext(self):
-            p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?" ], stderr = PIPE)
-            out, err = p.communicate()
+        p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?"], stderr=PIPE)
+        out, err = p.communicate()
 
-            print("Verify semanage fcontext -a")
-            p = Popen(["semanage", "fcontext", "-a", "-t", "httpd_sys_content_t", "/ha-web(/.*)?" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage fcontext -m")
-            p = Popen(["semanage", "fcontext", "-m", "-t", "default_t", "/ha-web(/.*)?" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage fcontext -d")
-            p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
+        print("Verify semanage fcontext -a")
+        p = Popen(["semanage", "fcontext", "-a", "-t", "httpd_sys_content_t", "/ha-web(/.*)?"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage fcontext -m")
+        p = Popen(["semanage", "fcontext", "-m", "-t", "default_t", "/ha-web(/.*)?"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage fcontext -d")
+        p = Popen(["semanage", "fcontext", "-d", "/ha-web(/.*)?"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
 
     def test_fcontext_e(self):
-            p = Popen(["semanage", "fcontext", "-d", "/myhome" ], stderr = PIPE)
-            out, err = p.communicate()
-            p = Popen(["semanage", "fcontext", "-d", "/myhome1" ], stderr = PIPE)
-            out, err = p.communicate()
+        p = Popen(["semanage", "fcontext", "-d", "/myhome"], stderr=PIPE)
+        out, err = p.communicate()
+        p = Popen(["semanage", "fcontext", "-d", "/myhome1"], stderr=PIPE)
+        out, err = p.communicate()
 
-            print("Verify semanage fcontext -a -e")
-            p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage fcontext -m -e")
-            p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome1" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage fcontext -d -e")
-            p = Popen(["semanage", "fcontext", "-d", "/myhome1" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
+        print("Verify semanage fcontext -a -e")
+        p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage fcontext -m -e")
+        p = Popen(["semanage", "fcontext", "-a", "-e", "/home", "/myhome1"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage fcontext -d -e")
+        p = Popen(["semanage", "fcontext", "-d", "/myhome1"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
 
     def test_port(self):
-            # Cleanup
-            p = Popen(["semanage", "port", "-d", "-p", "tcp", "55" ], stdout = PIPE, stderr = PIPE)
-            out, err = p.communicate()
+        # Cleanup
+        p = Popen(["semanage", "port", "-d", "-p", "tcp", "55"], stdout=PIPE, stderr=PIPE)
+        out, err = p.communicate()
 
-            # test
-            print("Verify semanage port -a")
-            p = Popen(["semanage", "port", "-a", "-t", "ssh_port_t", "-p", "tcp", "55" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage port -m")
-            p = Popen(["semanage", "port", "-m", "-t", "http_port_t", "-p", "tcp", "55" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage port -d")
-            p = Popen(["semanage", "port", "-d", "-p", "tcp", "55" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
+        # test
+        print("Verify semanage port -a")
+        p = Popen(["semanage", "port", "-a", "-t", "ssh_port_t", "-p", "tcp", "55"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage port -m")
+        p = Popen(["semanage", "port", "-m", "-t", "http_port_t", "-p", "tcp", "55"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage port -d")
+        p = Popen(["semanage", "port", "-d", "-p", "tcp", "55"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
 
     def test_login(self):
-            # Cleanup
-            p = Popen(["userdel", "-f", "-r", "testlogin" ], stderr = PIPE, stdout = PIPE)
-            out, err = p.communicate()
-            p = Popen(["semanage", "user", "-d", "testuser_u" ], stderr = PIPE, stdout = PIPE)
-            out, err = p.communicate()
-            p = Popen(["semanage", "login", "-d", "testlogin" ], stderr = PIPE, stdout = PIPE)
-            out, err = p.communicate()
+        # Cleanup
+        p = Popen(["userdel", "-f", "-r", "testlogin"], stderr=PIPE, stdout=PIPE)
+        out, err = p.communicate()
+        p = Popen(["semanage", "user", "-d", "testuser_u"], stderr=PIPE, stdout=PIPE)
+        out, err = p.communicate()
+        p = Popen(["semanage", "login", "-d", "testlogin"], stderr=PIPE, stdout=PIPE)
+        out, err = p.communicate()
 
-            #test
-            print("Verify semanage user -a")
-            p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify useradd ")
-            p = Popen(["useradd", "testlogin" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage login -a")
-            p = Popen(["semanage", "login", "-a", "-s", "testuser_u", "testlogin" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage login -m -r")
-            p = Popen(["semanage", "login", "-m", "-r", "s0-s0:c1", "testlogin" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage login -m -s")
-            p = Popen(["semanage", "login", "-m", "-s", "staff_u", "testlogin" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage login -m -s -r")
-            p = Popen(["semanage", "login", "-m", "-s", "testuser_u", "-r", "s0", "testlogin" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage login -d")
-            p = Popen(["semanage", "login", "-d", "testlogin" ], stdout = PIPE)
-            out, err = p.communicate()
-            print("Verify userdel ")
-            p = Popen(["userdel", "-f", "-r", "testlogin" ], stderr = PIPE, stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage user -d")
-            p = Popen(["semanage", "user", "-d", "testuser_u" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
+        #test
+        print("Verify semanage user -a")
+        p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify useradd ")
+        p = Popen(["useradd", "testlogin"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage login -a")
+        p = Popen(["semanage", "login", "-a", "-s", "testuser_u", "testlogin"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage login -m -r")
+        p = Popen(["semanage", "login", "-m", "-r", "s0-s0:c1", "testlogin"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage login -m -s")
+        p = Popen(["semanage", "login", "-m", "-s", "staff_u", "testlogin"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage login -m -s -r")
+        p = Popen(["semanage", "login", "-m", "-s", "testuser_u", "-r", "s0", "testlogin"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage login -d")
+        p = Popen(["semanage", "login", "-d", "testlogin"], stdout=PIPE)
+        out, err = p.communicate()
+        print("Verify userdel ")
+        p = Popen(["userdel", "-f", "-r", "testlogin"], stderr=PIPE, stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage user -d")
+        p = Popen(["semanage", "user", "-d", "testuser_u"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
 
     def test_user(self):
-            # Cleanup
-            p = Popen(["semanage", "user", "-d", "testuser_u" ], stderr = PIPE, stdout = PIPE)
-            out, err = p.communicate()
+        # Cleanup
+        p = Popen(["semanage", "user", "-d", "testuser_u"], stderr=PIPE, stdout=PIPE)
+        out, err = p.communicate()
 
-            # test
-            print("Verify semanage user -a")
-            p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage user -m -R")
-            p = Popen(["semanage", "user", "-m", "-R", "sysadm_r unconfined_r", "testuser_u" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage user -m -r")
-            p = Popen(["semanage", "user", "-m", "-r", "s0-s0:c1", "testuser_u" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
-            print("Verify semanage user -d")
-            p = Popen(["semanage", "user", "-d", "testuser_u" ], stdout = PIPE)
-            out, err = p.communicate()
-            self.assertSuccess(p.returncode, err)
+        # test
+        print("Verify semanage user -a")
+        p = Popen(["semanage", "user", "-a", "-R", "staff_r", "-r", "s0-s0:c0.c1023", "testuser_u"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage user -m -R")
+        p = Popen(["semanage", "user", "-m", "-R", "sysadm_r unconfined_r", "testuser_u"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage user -m -r")
+        p = Popen(["semanage", "user", "-m", "-r", "s0-s0:c1", "testuser_u"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
+        print("Verify semanage user -d")
+        p = Popen(["semanage", "user", "-d", "testuser_u"], stdout=PIPE)
+        out, err = p.communicate()
+        self.assertSuccess(p.returncode, err)
 
     def test_boolean(self):
         import selinux
-        boolean_status={0:"--off",1:"--on"}
-        boolean_state=selinux.security_get_boolean_active("httpd_anon_write")
+        boolean_status = {0: "--off", 1: "--on"}
+        boolean_state = selinux.security_get_boolean_active("httpd_anon_write")
         # Test
         print("Verify semanage boolean -m %s httpd_anon_write" % boolean_status[not boolean_state])
-        p = Popen(["semanage","boolean","-m",boolean_status[(not boolean_state)],"httpd_anon_write"], stdout = PIPE)
+        p = Popen(["semanage", "boolean", "-m", boolean_status[(not boolean_state)], "httpd_anon_write"], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
         print("Verify semanage boolean -m %s httpd_anon_write" % boolean_status[boolean_state])
-        p = Popen(["semanage","boolean","-m",boolean_status[boolean_state],"httpd_anon_write"], stdout = PIPE)
+        p = Popen(["semanage", "boolean", "-m", boolean_status[boolean_state], "httpd_anon_write"], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
+
 def semanage_suite():
     semanage_suite = unittest.TestSuite()
     semanage_suite.addTest(unittest.makeSuite(SemanageTests))
 
     return semanage_suite
 
+
 def semanage_custom_suite(test_list):
-    suiteSemanage=unittest.TestSuite()
+    suiteSemanage = unittest.TestSuite()
     for t in test_list:
         suiteSemanage.addTest(SemanageTests(t))
 
     return suiteSemanage
 
+
 def semanage_run_test(suite):
     unittest.TextTestRunner(verbosity=2).run(suite)
 
+
 class CheckTest(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         newval = getattr(namespace, self.dest)
         if not newval:
@@ -240,6 +251,7 @@
             newval.append(v)
         setattr(namespace, self.dest, newval)
 
+
 def semanage_args(args):
     if args.list:
         print("You can run the following tests:")
@@ -250,22 +262,23 @@
     if args.test:
         semanage_run_test(semanage_custom_suite(args.test))
 
+
 def gen_semanage_test_args(parser):
     group = parser.add_mutually_exclusive_group(required=True)
     group.add_argument('-a', "--all", dest="all", default=False,
-                        action="store_true",
-                        help=("Run all semanage unit tests"))
+                       action="store_true",
+                       help=("Run all semanage unit tests"))
     group.add_argument('-l', "--list", dest="list", default=False,
-                        action="store_true",
-                        help=("List all semanage unit tests"))
+                       action="store_true",
+                       help=("List all semanage unit tests"))
     group.add_argument('-t', "--test", dest="test", default=[],
-                        action=CheckTest, nargs="*",
-                        help=("Run selected semanage unit test(s)"))
+                       action=CheckTest, nargs="*",
+                       help=("Run selected semanage unit test(s)"))
     group.set_defaults(func=semanage_args)
 
 if __name__ == "__main__":
     import selinux
-    semanage_test_list=filter(lambda x: x.startswith("test_"), dir(SemanageTests))
+    semanage_test_list = filter(lambda x: x.startswith("test_"), dir(SemanageTests))
     if selinux.security_getenforce() == 1:
         parser = argparse.ArgumentParser(description='Semanage unit test script')
         gen_semanage_test_args(parser)
@@ -273,10 +286,10 @@
             args = parser.parse_args()
             args.func(args)
             sys.exit(0)
-        except ValueError,e:
+        except ValueError as e:
             sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
             sys.exit(1)
-        except IOError,e:
+        except IOError as e:
             sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
             sys.exit(1)
         except KeyboardInterrupt:
diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
index dde0efb..9cd04e7 100644
--- a/policycoreutils/semodule/semodule.8
+++ b/policycoreutils/semodule/semodule.8
@@ -41,6 +41,11 @@
 .B  \-l,\-\-list-modules=[KIND]
 display list of installed modules (other than base)
 .TP
+.B  \-E,\-\-extract=MODULE_PKG
+Extract a module from the store as an HLL or CIL file to the current directory.
+A module is extracted as HLL by default. The name of the module written is
+<module-name>.<lang_ext>
+.TP
 .B  KIND:
 .TP
 standard
@@ -81,6 +86,12 @@
 .TP
 .B  \-v,\-\-verbose     
 be verbose
+.TP
+.B  \-c,\-\-cil
+Extract module as a CIL file. This only affects the \-\-extract option.
+.TP
+.B  \-H,\-\-hll
+Extract module as an HLL file. This only affects the \-\-extract option.
 
 .SH EXAMPLE
 .nf
@@ -108,6 +119,9 @@
 $ semodule \-B \-p "/tmp"
 # Set an alternate path for the policy store root
 $ semodule \-B \-S "/tmp/var/lib/selinux"
+# Write the HLL version of puppet and the CIL version of wireshark
+# modules at priority 400 to the current working directory
+$ semodule \-X 400 \-g wireshark \-\-cil \-g puppet \-\-hll
 .fi
 
 .SH SEE ALSO
diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
index baff057..bcfaa2b 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -20,16 +20,17 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <libgen.h>
+#include <limits.h>
 
 #include <semanage/modules.h>
 
 enum client_modes {
-	NO_MODE, INSTALL_M, REMOVE_M,
+	NO_MODE, INSTALL_M, REMOVE_M, EXTRACT_M, CIL_M, HLL_M,
 	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
 };
 /* list of modes in which one ought to commit afterwards */
 static const int do_commit[] = {
-	0, 1, 1,
+	0, 1, 1, 0, 0, 0,
 	0, 0, 0, 1, 1,
 };
 
@@ -49,10 +50,12 @@
 static int preserve_tunables;
 static int ignore_module_cache;
 static uint16_t priority;
+static int priority_set = 0;
 
 static semanage_handle_t *sh = NULL;
 static char *store;
 static char *store_root;
+int extract_cil = 0;
 
 extern char *optarg;
 extern int optind;
@@ -130,6 +133,7 @@
 	printf("  -X,--priority=PRIORITY    set priority for following operations (1-999)\n");
 	printf("  -e,--enable=MODULE_NAME   enable module\n");
 	printf("  -d,--disable=MODULE_NAME  disable module\n");
+	printf("  -E,--extract=MODULE_NAME  extract module\n");
 	printf("Other options:\n");
 	printf("  -s,--store	   name of the store to operate on\n");
 	printf("  -N,-n,--noreload do not reload policy after commit\n");
@@ -140,6 +144,8 @@
 	printf("  -C,--ignore-module-cache	Rebuild CIL modules compiled from HLL files\n");
 	printf("  -p,--path        use an alternate path for the policy root\n");
 	printf("  -S,--store-path  use an alternate path for the policy store root\n");
+	printf("  -c, --cil extract module as cil. This only affects module extraction.\n");
+	printf("  -H, --hll extract module as hll. This only affects module extraction.\n");
 }
 
 /* Sets the global mode variable to new_mode, but only if no other
@@ -175,6 +181,9 @@
 		{"base", required_argument, NULL, 'b'},
 		{"help", 0, NULL, 'h'},
 		{"install", required_argument, NULL, 'i'},
+		{"extract", required_argument, NULL, 'E'},
+		{"cil", 0, NULL, 'c'},
+		{"hll", 0, NULL, 'H'},
 		{"list-modules", optional_argument, NULL, 'l'},
 		{"verbose", 0, NULL, 'v'},
 		{"remove", required_argument, NULL, 'r'},
@@ -192,13 +201,15 @@
 		{"store-path", required_argument, NULL, 'S'},
 		{NULL, 0, NULL, 0}
 	};
+	int extract_selected = 0;
+	int cil_hll_set = 0;
 	int i;
 	verbose = 0;
 	reload = 0;
 	no_reload = 0;
 	priority = 400;
 	while ((i =
-		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnNBDCPX:e:d:p:S:", opts,
+		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnNBDCPX:e:d:p:S:E:cH", opts,
 			    NULL)) != -1) {
 		switch (i) {
 		case 'b':
@@ -211,6 +222,18 @@
 		case 'i':
 			set_mode(INSTALL_M, optarg);
 			break;
+		case 'E':
+			set_mode(EXTRACT_M, optarg);
+			extract_selected = 1;
+			break;
+		case 'c':
+			set_mode(CIL_M, NULL);
+			cil_hll_set = 1;
+			break;
+		case 'H':
+			set_mode(HLL_M, NULL);
+			cil_hll_set = 1;
+			break;
 		case 'l':
 			set_mode(LIST_M, optarg);
 			break;
@@ -281,10 +304,15 @@
 		usage(argv[0]);
 		exit(1);
 	}
+	if (extract_selected == 0 && cil_hll_set == 1) {
+		fprintf(stderr, "--cil and --hll require a module to export with the --extract option.\n");
+		usage(argv[0]);
+		exit(1);
+	}
 
 	if (optind < argc) {
 		int mode;
-		/* if -i/u/r was the last command treat any remaining
+		/* if -i/u/r/E was the last command treat any remaining
 		 * arguments as args. Will allow 'semodule -i *.pp' to
 		 * work as expected.
 		 */
@@ -293,6 +321,8 @@
 			mode = INSTALL_M;
 		} else if (commands && commands[num_commands - 1].mode == REMOVE_M) {
 			mode = REMOVE_M;
+		} else if (commands && commands[num_commands - 1].mode == EXTRACT_M) {
+			mode = EXTRACT_M;
 		} else {
 			fprintf(stderr, "unknown additional arguments:\n");
 			while (optind < argc)
@@ -389,6 +419,113 @@
 				    semanage_module_install_file(sh, mode_arg);
 				break;
 			}
+		case EXTRACT_M:{
+				semanage_module_info_t *extract_info = NULL;
+				semanage_module_key_t *modkey = NULL;
+				uint16_t curr_priority;
+				void *data = NULL;
+				size_t data_len = 0;
+				char output_path[PATH_MAX];
+				const char *output_name = NULL;
+				const char *lang_ext = NULL;
+				int rlen;
+				FILE *output_fd = NULL;
+
+				result = semanage_module_key_create(sh, &modkey);
+				if (result != 0) {
+					goto cleanup_extract;
+				}
+
+				result = semanage_module_key_set_name(sh, modkey, mode_arg);
+				if (result != 0) {
+					goto cleanup_extract;
+				}
+
+				if (priority_set == 0) {
+					result = semanage_module_get_module_info(sh, modkey, &extract_info);
+					if (result != 0) {
+						goto cleanup_extract;
+					}
+
+					semanage_module_info_get_priority(sh, extract_info, &curr_priority);
+					printf("Module '%s' does not exist at the default priority '%d'. "
+							"Extracting at highest existing priority '%d'.\n", mode_arg, priority, curr_priority);
+					priority = curr_priority;
+				}
+
+				result  = semanage_module_key_set_priority(sh, modkey, priority);
+				if (result != 0) {
+					goto cleanup_extract;
+				}
+
+				if (verbose) {
+					printf
+						("Attempting to extract module '%s':\n",
+							mode_arg);
+				}
+				result = semanage_module_extract(sh, modkey, extract_cil, &data, &data_len, &extract_info);
+				if (result != 0) {
+					goto cleanup_extract;
+				}
+
+				if (extract_cil) {
+					lang_ext = "cil";
+				} else {
+					result = semanage_module_info_get_lang_ext(sh, extract_info, &lang_ext);
+					if (result != 0) {
+						goto cleanup_extract;
+					}
+				}
+
+				result = semanage_module_info_get_name(sh, extract_info, &output_name);
+				if (result != 0) {
+					goto cleanup_extract;
+				}
+
+				rlen = snprintf(output_path, PATH_MAX, "%s.%s", output_name, lang_ext);
+				if (rlen < 0 || rlen >= PATH_MAX) {
+					fprintf(stderr, "%s: Failed to generate output path.\n", argv[0]);
+					result = -1;
+					goto cleanup_extract;
+				}
+
+				if (access(output_path, F_OK) == 0) {
+					fprintf(stderr, "%s: %s is already extracted with extension %s.\n", argv[0], mode_arg, lang_ext);
+					result = -1;
+					goto cleanup_extract;
+				}
+
+				output_fd = fopen(output_path, "w");
+				if (output_fd == NULL) {
+					fprintf(stderr, "%s: Unable to open %s\n", argv[0], output_path);
+					result = -1;
+					goto cleanup_extract;
+				}
+
+				if (fwrite(data, 1, data_len, output_fd) < data_len) {
+					fprintf(stderr, "%s: Unable to write to %s\n", argv[0], output_path);
+					result = -1;
+					goto cleanup_extract;
+				}
+cleanup_extract:
+				if (output_fd != NULL) {
+					fclose(output_fd);
+				}
+				if (data_len > 0) {
+					munmap(data, data_len);
+				}
+				semanage_module_info_destroy(sh, extract_info);
+				free(extract_info);
+				semanage_module_key_destroy(sh, modkey);
+				free(modkey);
+				break;
+			}
+		case CIL_M:
+				extract_cil = 1;
+				break;
+		case HLL_M:
+				extract_cil = 0;
+				break;
 		case REMOVE_M:{
 				if (verbose) {
 					printf
@@ -515,6 +652,7 @@
 		case PRIORITY_M:{
 				char *endptr = NULL;
 				priority = (uint16_t)strtoul(mode_arg, &endptr, 10);
+				priority_set = 1;
 
 				if ((result = semanage_set_default_priority(sh, priority)) != 0) {
 					fprintf(stderr,
diff --git a/policycoreutils/sepolicy/selinux_client.py b/policycoreutils/sepolicy/selinux_client.py
index 458a4d2..7f4a91c 100644
--- a/policycoreutils/sepolicy/selinux_client.py
+++ b/policycoreutils/sepolicy/selinux_client.py
@@ -2,6 +2,7 @@
 import dbus.service
 from sepolicy.sedbus import SELinuxDBus
 
+
 def convert_customization(buf):
     cust_dict = {}
     cust_dict["fcontext-equiv"] = {}
@@ -14,24 +15,24 @@
         if rec[0] not in cust_dict:
             cust_dict[rec[0]] = {}
         if rec[0] == "boolean":
-            cust_dict["boolean"][rec[-1]] = { "active": rec[2] == "-1" }
+            cust_dict["boolean"][rec[-1]] = {"active": rec[2] == "-1"}
         if rec[0] == "login":
-            cust_dict["login"][rec[-1]] = { "seuser": rec[3], "range": rec[5] }
+            cust_dict["login"][rec[-1]] = {"seuser": rec[3], "range": rec[5]}
         if rec[0] == "interface":
-            cust_dict["login"][rec[-1]] = { "type": rec[3] }
+            cust_dict["login"][rec[-1]] = {"type": rec[3]}
         if rec[0] == "user":
-            cust_dict["user"][rec[-1]] = { "level": rec[3], "range": rec[5], "role": rec[7] }
+            cust_dict["user"][rec[-1]] = {"level": rec[3], "range": rec[5], "role": rec[7]}
         if rec[0] == "port":
-            cust_dict["port"][(rec[-1], rec[-2] )] = { "type": rec[3] }
+            cust_dict["port"][(rec[-1], rec[-2])] = {"type": rec[3]}
         if rec[0] == "node":
-            cust_dict["node"][rec[-1]] = { "mask": rec[3], "protocol":rec[5], "type": rec[7] }
+            cust_dict["node"][rec[-1]] = {"mask": rec[3], "protocol": rec[5], "type": rec[7]}
         if rec[0] == "fcontext":
             if rec[2] == "-e":
-                cust_dict["fcontext-equiv"][(rec[-1])] = { "equiv": rec[3] }
+                cust_dict["fcontext-equiv"][(rec[-1])] = {"equiv": rec[3]}
             else:
-                cust_dict["fcontext"][(rec[-1],rec[3])] = { "type": rec[5] }
+                cust_dict["fcontext"][(rec[-1], rec[3])] = {"type": rec[5]}
         if rec[0] == "module":
-            cust_dict["module"][rec[-1]] = { "enabled": rec[2] != "-d" }
+            cust_dict["module"][rec[-1]] = {"enabled": rec[2] != "-d"}
 
     return cust_dict
 if __name__ == "__main__":
diff --git a/policycoreutils/sepolicy/selinux_server.py b/policycoreutils/sepolicy/selinux_server.py
index e94c38f..cdf4d16 100644
--- a/policycoreutils/sepolicy/selinux_server.py
+++ b/policycoreutils/sepolicy/selinux_server.py
@@ -10,9 +10,11 @@
 import selinux
 from subprocess import Popen, PIPE, STDOUT
 
+
 class selinux_server(slip.dbus.service.Object):
     default_polkit_auth_required = "org.selinux.semanage"
-    def __init__ (self, *p, **k):
+
+    def __init__(self, *p, **k):
         super(selinux_server, self).__init__(*p, **k)
 
     #
@@ -22,7 +24,7 @@
     @slip.dbus.polkit.require_auth("org.selinux.semanage")
     @dbus.service.method("org.selinux", in_signature='s')
     def semanage(self, buf):
-        p = Popen(["/usr/sbin/semanage", "import"],stdout=PIPE, stderr=PIPE, stdin=PIPE)
+        p = Popen(["/usr/sbin/semanage", "import"], stdout=PIPE, stderr=PIPE, stdin=PIPE)
         p.stdin.write(buf)
         output = p.communicate()
         if p.returncode and p.returncode != 0:
@@ -36,7 +38,7 @@
     @slip.dbus.polkit.require_auth("org.selinux.customized")
     @dbus.service.method("org.selinux", in_signature='', out_signature='s')
     def customized(self):
-        p = Popen(["/usr/sbin/semanage", "export"],stdout=PIPE, stderr=PIPE)
+        p = Popen(["/usr/sbin/semanage", "export"], stdout=PIPE, stderr=PIPE)
         buf = p.stdout.read()
         output = p.communicate()
         if p.returncode and p.returncode != 0:
@@ -50,7 +52,7 @@
     @slip.dbus.polkit.require_auth("org.selinux.semodule_list")
     @dbus.service.method("org.selinux", in_signature='', out_signature='s')
     def semodule_list(self):
-        p = Popen(["/usr/sbin/semodule", "-l"],stdout=PIPE, stderr=PIPE)
+        p = Popen(["/usr/sbin/semodule", "-l"], stdout=PIPE, stderr=PIPE)
         buf = p.stdout.read()
         output = p.communicate()
         if p.returncode and p.returncode != 0:
@@ -80,7 +82,7 @@
     @dbus.service.method("org.selinux", in_signature='i')
     def relabel_on_boot(self, value):
         if value == 1:
-            fd = open("/.autorelabel","w")
+            fd = open("/.autorelabel", "w")
             fd.close()
         else:
             os.unlink("/.autorelabel")
@@ -109,12 +111,11 @@
     @slip.dbus.polkit.require_auth("org.selinux.change_default_mode")
     @dbus.service.method("org.selinux", in_signature='s')
     def change_default_mode(self, value):
-        values = [ "enforcing", "permissive", "disabled" ]
+        values = ["enforcing", "permissive", "disabled"]
         if value not in values:
             raise ValueError("Enforcement mode must be %s" % ", ".join(values))
         self.write_selinux_config(enforcing=value)
 
-
     #
     # The change_default_policy method modifies the policy type
     #
@@ -127,10 +128,10 @@
         raise ValueError("%s does not exist" % path)
 
 if __name__ == "__main__":
-        mainloop = gobject.MainLoop()
-        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
-        system_bus = dbus.SystemBus()
-        name = dbus.service.BusName("org.selinux", system_bus)
-        object = selinux_server(system_bus, "/org/selinux/object")
-        slip.dbus.service.set_mainloop(mainloop)
-        mainloop.run()
+    mainloop = gobject.MainLoop()
+    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+    system_bus = dbus.SystemBus()
+    name = dbus.service.BusName("org.selinux", system_bus)
+    object = selinux_server(system_bus, "/org/selinux/object")
+    slip.dbus.service.set_mainloop(mainloop)
+    mainloop.run()
diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py
index 74fb347..08a5c2f 100755
--- a/policycoreutils/sepolicy/sepolicy.py
+++ b/policycoreutils/sepolicy/sepolicy.py
@@ -21,38 +21,43 @@
 #                                        02111-1307  USA
 #
 #
-import os, sys
+import os
+import sys
 import selinux
 import sepolicy
 from sepolicy import get_os_version, get_conditionals, get_conditionals_format_text
 import argparse
 import gettext
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
 try:
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
 usage = "sepolicy generate [-h] [-n NAME] [-p PATH] ["
-usage_dict = {' --newtype':('-t [TYPES [TYPES ...]]',),' --customize':('-d DOMAIN','-a  ADMIN_DOMAIN',"[ -w WRITEPATHS ]",), ' --admin_user':('[-r TRANSITION_ROLE ]',"[ -w WRITEPATHS ]",), ' --application':('COMMAND',"[ -w WRITEPATHS ]",), ' --cgi':('COMMAND',"[ -w WRITEPATHS ]",), ' --confined_admin':('-a  ADMIN_DOMAIN',"[ -w WRITEPATHS ]",), ' --dbus':('COMMAND',"[ -w WRITEPATHS ]",), ' --desktop_user':('',"[ -w WRITEPATHS ]",),' --inetd':('COMMAND',"[ -w WRITEPATHS ]",),' --init':('COMMAND',"[ -w WRITEPATHS ]",), ' --sandbox':("[ -w WRITEPATHS ]",), ' --term_user':("[ -w WRITEPATHS ]",), ' --x_user':("[ -w WRITEPATHS ]",)}
+usage_dict = {' --newtype': ('-t [TYPES [TYPES ...]]',), ' --customize': ('-d DOMAIN', '-a  ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --admin_user': ('[-r TRANSITION_ROLE ]', "[ -w WRITEPATHS ]",), ' --application': ('COMMAND', "[ -w WRITEPATHS ]",), ' --cgi': ('COMMAND', "[ -w WRITEPATHS ]",), ' --confined_admin': ('-a  ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --dbus': ('COMMAND', "[ -w WRITEPATHS ]",), ' --desktop_user': ('', "[ -w WRITEPATHS ]",), ' --inetd': ('COMMAND', "[ -w WRITEPATHS ]",), ' --init': ('COMMAND', "[ -w WRITEPATHS ]",), ' --sandbox': ("[ -w WRITEPATHS ]",), ' --term_user': ("[ -w WRITEPATHS ]",), ' --x_user': ("[ -w WRITEPATHS ]",)}
+
 
 class CheckPath(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         if not os.path.exists(values):
-                raise ValueError("%s does not exist" % values)
+            raise ValueError("%s does not exist" % values)
         setattr(namespace, self.dest, values)
 
+
 class CheckType(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         domains = sepolicy.get_all_domains()
 
-        if isinstance(values,str):
+        if isinstance(values, str):
             setattr(namespace, self.dest, values)
         else:
             newval = getattr(namespace, self.dest)
@@ -63,14 +68,16 @@
                 newval.append(v)
             setattr(namespace, self.dest, newval)
 
+
 class CheckBoolean(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         booleans = sepolicy.get_all_booleans()
         newval = getattr(namespace, self.dest)
         if not newval:
             newval = []
 
-        if isinstance(values,str):
+        if isinstance(values, str):
             v = selinux.selinux_boolean_sub(values)
             if v not in booleans:
                 raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(booleans)))
@@ -84,11 +91,13 @@
                 newval.append(v)
             setattr(namespace, self.dest, newval)
 
+
 class CheckDomain(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         domains = sepolicy.get_all_domains()
 
-        if isinstance(values,str):
+        if isinstance(values, str):
             if values not in domains:
                 raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (values, ", ".join(domains)))
             setattr(namespace, self.dest, values)
@@ -104,17 +113,22 @@
             setattr(namespace, self.dest, newval)
 
 all_classes = None
+
+
 class CheckClass(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         global all_classes
         if not all_classes:
-                all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS))
+            all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS))
         if values not in all_classes:
             raise ValueError("%s must be an SELinux class:\nValid classes: %s" % (values, ", ".join(all_classes)))
 
         setattr(namespace, self.dest, values)
 
+
 class CheckAdmin(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         from sepolicy.interface import get_admin
         newval = getattr(namespace, self.dest)
@@ -126,7 +140,9 @@
         newval.append(values)
         setattr(namespace, self.dest, newval)
 
+
 class CheckPort(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         newval = getattr(namespace, self.dest)
         if not newval:
@@ -137,7 +153,9 @@
             newval.append(v)
         setattr(namespace, self.dest, newval)
 
+
 class CheckPortType(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         port_types = sepolicy.get_all_port_types()
         newval = getattr(namespace, self.dest)
@@ -149,13 +167,17 @@
             newval.append(v)
         setattr(namespace, self.dest, values)
 
+
 class LoadPolicy(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         import sepolicy
         sepolicy.policy(values)
         setattr(namespace, self.dest, values)
 
+
 class CheckPolicyType(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
         from sepolicy.generate import get_poltype_desc, poltype
         if values not in poltype.keys():
@@ -163,31 +185,37 @@
             newval.append(v)
         setattr(namespace, self.dest, values)
 
+
 class CheckUser(argparse.Action):
+
     def __call__(self, parser, namespace, value, option_string=None):
         newval = getattr(namespace, self.dest)
         if not newval:
             newval = []
         users = sepolicy.get_all_users()
         if value not in users:
-                raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users)))
+            raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users)))
         newval.append(value)
         setattr(namespace, self.dest, newval)
 
+
 class CheckRole(argparse.Action):
+
     def __call__(self, parser, namespace, value, option_string=None):
         newval = getattr(namespace, self.dest)
         if not newval:
             newval = []
         roles = sepolicy.get_all_roles()
         if value not in roles:
-                raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles)))
+            raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles)))
         newval.append(value[:-2])
         setattr(namespace, self.dest, newval)
 
+
 class InterfaceInfo(argparse.Action):
+
     def __call__(self, parser, namespace, values, option_string=None):
-	from sepolicy.interface import get_interface_dict
+        from sepolicy.interface import get_interface_dict
         interface_dict = get_interface_dict()
         for v in values:
             if v not in interface_dict.keys():
@@ -195,19 +223,21 @@
 
         setattr(namespace, self.dest, values)
 
-def generate_custom_usage(usage_text,usage_dict):
+
+def generate_custom_usage(usage_text, usage_dict):
     sorted_keys = []
     for i in usage_dict.keys():
         sorted_keys.append(i)
     sorted_keys.sort()
     for k in sorted_keys:
-        usage_text += "%s %s |" % (k,(" ".join(usage_dict[k])))
+        usage_text += "%s %s |" % (k, (" ".join(usage_dict[k])))
     usage_text = usage_text[:-1] + "]"
     usage_text = _(usage_text)
 
     return usage_text
 
-def numcmp(val1,val2):
+
+def numcmp(val1, val2):
     try:
         v1 = int(val1.split(",")[0].split("-")[0])
         v2 = int(val2.split(",")[0].split("-")[0])
@@ -218,28 +248,30 @@
         if v1 < v2:
             return -1
     except:
-        return cmp(val1,val2)
+        return cmp(val1, val2)
+
 
 def _print_net(src, protocol, perm):
     import sepolicy.network
     portdict = sepolicy.network.get_network_connect(src, protocol, perm)
     if len(portdict) > 0:
-        bold_start="\033[1m"
-        bold_end="\033[0;0m"
-        print "\n"+bold_start+"%s: %s %s" % (src, protocol, perm) + bold_end
-        port_strings=[]
-        boolean_text=""
+        bold_start = "\033[1m"
+        bold_end = "\033[0;0m"
+        print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
+        port_strings = []
+        boolean_text = ""
         for p in portdict:
             for t, recs in portdict[p]:
-                cond=get_conditionals(src,t,"%s_socket" % protocol, [perm])
+                cond = get_conditionals(src, t, "%s_socket" % protocol, [perm])
                 if cond:
-                    boolean_text=get_conditionals_format_text(cond)
+                    boolean_text = get_conditionals_format_text(cond)
                     port_strings.append("%s (%s) %s" % (", ".join(recs), t, boolean_text))
                 else:
                     port_strings.append("%s (%s)" % (", ".join(recs), t))
         port_strings.sort(numcmp)
         for p in port_strings:
-                print "\t" + p
+            print "\t" + p
+
 
 def network(args):
     portrecs, portrecsbynum = sepolicy.gen_port_dict()
@@ -268,10 +300,10 @@
                 print "Undefined port type"
 
     for t in args.type:
-        if (t,'tcp') in portrecs.keys():
-            print "%s: tcp: %s" % (t, ",".join(portrecs[t,'tcp']))
-        if (t,'udp') in portrecs.keys():
-            print "%s: udp: %s" % (t, ",".join(portrecs[t,'udp']))
+        if (t, 'tcp') in portrecs.keys():
+            print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
+        if (t, 'udp') in portrecs.keys():
+            print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))
 
     for a in args.applications:
         d = sepolicy.get_init_transtype(a)
@@ -283,6 +315,7 @@
         for net in ("tcp", "udp"):
             _print_net(d, net, "name_bind")
 
+
 def gui_run(args):
     try:
         import sepolicy.gui
@@ -291,16 +324,18 @@
     except ImportError:
         raise ValueError(_("You need to install policycoreutils-gui package to use the gui option"))
 
+
 def gen_gui_args(parser):
     gui = parser.add_parser("gui",
                             help=_('Graphical User Interface for SELinux Policy'))
     gui.add_argument("-d", "--domain", default=None,
-                       action=CheckDomain,
-                       help=_("Domain name(s) of man pages to be created"))
+                     action=CheckDomain,
+                     help=_("Domain name(s) of man pages to be created"))
     gui.add_argument("-t", "--test", default=False, action="store_true",
-                       help=argparse.SUPPRESS)
+                     help=argparse.SUPPRESS)
     gui.set_defaults(func=gui_run)
 
+
 def manpage(args):
     from sepolicy.manpage import ManPage, HTMLManPages, manpage_domains, manpage_roles, gen_domains
 
@@ -316,12 +351,13 @@
         test_domains = args.domain
 
     for domain in test_domains:
-        m = ManPage(domain, path, args.root,args.source_files, args.web)
+        m = ManPage(domain, path, args.root, args.source_files, args.web)
         print m.get_man_page_path()
 
     if args.web:
         HTMLManPages(manpage_roles, manpage_domains, path, args.os)
 
+
 def gen_manpage_args(parser):
     man = parser.add_parser("manpage",
                             help=_('Generate SELinux man pages'))
@@ -345,37 +381,40 @@
                        help=_("Domain name(s) of man pages to be created"))
     man.set_defaults(func=manpage)
 
-def gen_network_args(parser):
-        net = parser.add_parser("network",
-                                   help=_('Query SELinux policy network information'))
 
-        group = net.add_mutually_exclusive_group(required=True)
-        group.add_argument("-l", "--list", dest="list_ports",
-                           action="store_true",
-                            help=_("list all SELinux port types"))
-        group.add_argument("-p", "--port", dest="port", default=[],
-                            action=CheckPort, nargs="+", type=int,
-                            help=_("show SELinux type related to the port"))
-        group.add_argument("-t", "--type", dest="type", default=[],
-                            action=CheckPortType,nargs="+",
-                            help=_("Show ports defined for this SELinux type"))
-        group.add_argument("-d", "--domain", dest="domain", default=[],
-                            action=CheckDomain, nargs="+",
-                            help=_("show ports to which this domain can bind and/or connect"))
-        group.add_argument("-a", "--application", dest="applications", default=[],
-                           nargs="+",
-                           help=_("show ports to which this application can bind and/or connect"))
-        net.set_defaults(func=network)
+def gen_network_args(parser):
+    net = parser.add_parser("network",
+                            help=_('Query SELinux policy network information'))
+
+    group = net.add_mutually_exclusive_group(required=True)
+    group.add_argument("-l", "--list", dest="list_ports",
+                       action="store_true",
+                       help=_("list all SELinux port types"))
+    group.add_argument("-p", "--port", dest="port", default=[],
+                       action=CheckPort, nargs="+", type=int,
+                       help=_("show SELinux type related to the port"))
+    group.add_argument("-t", "--type", dest="type", default=[],
+                       action=CheckPortType, nargs="+",
+                       help=_("Show ports defined for this SELinux type"))
+    group.add_argument("-d", "--domain", dest="domain", default=[],
+                       action=CheckDomain, nargs="+",
+                       help=_("show ports to which this domain can bind and/or connect"))
+    group.add_argument("-a", "--application", dest="applications", default=[],
+                       nargs="+",
+                       help=_("show ports to which this application can bind and/or connect"))
+    net.set_defaults(func=network)
+
 
 def communicate(args):
-        from sepolicy.communicate import get_types
+    from sepolicy.communicate import get_types
 
-        writable = get_types(args.source, args.tclass, args.sourceaccess.split(","))
-        readable = get_types(args.target, args.tclass, args.targetaccess.split(","))
-        out = list(set(writable) & set(readable))
+    writable = get_types(args.source, args.tclass, args.sourceaccess.split(","))
+    readable = get_types(args.target, args.tclass, args.targetaccess.split(","))
+    out = list(set(writable) & set(readable))
 
-        for t in out:
-            print t
+    for t in out:
+        print t
+
 
 def gen_communicate_args(parser):
     comm = parser.add_parser("communicate",
@@ -389,10 +428,11 @@
     comm.add_argument("-c", "--class", required=False, dest="tclass",
                       action=CheckClass,
                       default="file", help="class to use for communications, Default 'file'")
-    comm.add_argument("-S", "--sourceaccess", required=False, dest="sourceaccess",  default="open,write", help="comma separate list of permissions for the source type to use, Default 'open,write'")
-    comm.add_argument("-T", "--targetaccess", required=False, dest="targetaccess",  default="open,read", help="comma separated list of permissions for the target type to use, Default 'open,read'")
+    comm.add_argument("-S", "--sourceaccess", required=False, dest="sourceaccess", default="open,write", help="comma separate list of permissions for the source type to use, Default 'open,write'")
+    comm.add_argument("-T", "--targetaccess", required=False, dest="targetaccess", default="open,read", help="comma separated list of permissions for the target type to use, Default 'open,read'")
     comm.set_defaults(func=communicate)
 
+
 def booleans(args):
     from sepolicy import boolean_desc
     if args.all:
@@ -402,6 +442,7 @@
     for b in args.booleans:
         print "%s=_(\"%s\")" % (b, boolean_desc(b))
 
+
 def gen_booleans_args(parser):
     bools = parser.add_parser("booleans",
                               help=_('query SELinux Policy to see description of booleans'))
@@ -414,11 +455,13 @@
                        help=_("boolean to get description"))
     bools.set_defaults(func=booleans)
 
+
 def transition(args):
     from sepolicy.transition import setrans
     mytrans = setrans(args.source, args.target)
     mytrans.output()
 
+
 def gen_transition_args(parser):
     trans = parser.add_parser("transition",
                               help=_('query SELinux Policy to see how a source process domain can transition to the target process domain'))
@@ -430,6 +473,7 @@
                        help=_("target process domain"))
     trans.set_defaults(func=transition)
 
+
 def print_interfaces(interfaces, args, append=""):
     from sepolicy.interface import get_interface_format_text, interface_compile_test
     for i in interfaces:
@@ -446,6 +490,7 @@
         else:
             print i
 
+
 def interface(args):
     from sepolicy.interface import get_admin, get_user, get_interface_dict, get_all_interfaces
     if args.list_admin:
@@ -455,13 +500,14 @@
     if args.list:
         print_interfaces(get_all_interfaces(args.file), args)
     if args.interfaces:
-            print_interfaces(args.interfaces, args)
+        print_interfaces(args.interfaces, args)
+
 
 def generate(args):
     from sepolicy.generate import policy, AUSER, RUSER, EUSER, USERS, SANDBOX, APPLICATIONS, NEWTYPE
     cmd = None
 # numbers present POLTYPE defined in sepolicy.generate
-    conflict_args = {'TYPES':(NEWTYPE,), 'DOMAIN':(EUSER,), 'ADMIN_DOMAIN':(AUSER, RUSER, EUSER,)}
+    conflict_args = {'TYPES': (NEWTYPE,), 'DOMAIN': (EUSER,), 'ADMIN_DOMAIN': (AUSER, RUSER, EUSER,)}
     error_text = ""
 
     if args.policytype is None:
@@ -477,7 +523,7 @@
             raise ValueError(_("Command required for this type of policy"))
         cmd = os.path.realpath(args.command)
         if not args.name:
-            args.name = os.path.basename(cmd).replace("-","_")
+            args.name = os.path.basename(cmd).replace("-", "_")
 
     mypolicy = policy(args.name, args.policytype)
     if cmd:
@@ -498,7 +544,7 @@
 
     if len(args.writepaths) > 0 and args.policytype == NEWTYPE:
 
-            raise ValueError(_("-w option can not be used with the --newtype option"))
+        raise ValueError(_("-w option can not be used with the --newtype option"))
 
     for p in args.writepaths:
         if os.path.isdir(p):
@@ -516,6 +562,7 @@
         mypolicy.gen_symbols()
     print mypolicy.generate(args.path)
 
+
 def gen_interface_args(parser):
     itf = parser.add_parser("interface",
                             help=_('List SELinux Policy interfaces'))
@@ -528,12 +575,12 @@
     itf.add_argument("-f", "--file", dest="file",
                      help="Interface file")
     group = itf.add_mutually_exclusive_group(required=True)
-    group.add_argument("-a", "--list_admin", dest="list_admin",action="store_true",                       default=False,
+    group.add_argument("-a", "--list_admin", dest="list_admin", action="store_true", default=False,
                        help="List all domains with admin interface - DOMAIN_admin()")
-    group.add_argument("-u", "--list_user", dest="list_user",action="store_true",
+    group.add_argument("-u", "--list_user", dest="list_user", action="store_true",
                        default=False,
                        help="List all domains with SELinux user role interface - DOMAIN_role()")
-    group.add_argument("-l", "--list", dest="list",action="store_true",
+    group.add_argument("-l", "--list", dest="list", action="store_true",
                        default=False,
                        help="List all interfaces")
     group.add_argument("-i", "--interfaces", nargs="+", dest="interfaces",
@@ -541,23 +588,24 @@
                        help=_("Enter interface names, you wish to query"))
     itf.set_defaults(func=interface)
 
+
 def gen_generate_args(parser):
     from sepolicy.generate import DAEMON, get_poltype_desc, poltype, DAEMON, DBUS, INETD, CGI, SANDBOX, USER, EUSER, TUSER, XUSER, LUSER, AUSER, RUSER, NEWTYPE
 
     generate_usage = generate_custom_usage(usage, usage_dict)
 
-    pol = parser.add_parser("generate", usage = generate_usage,
+    pol = parser.add_parser("generate", usage=generate_usage,
                             help=_('Generate SELinux Policy module template'))
     pol.add_argument("-d", "--domain", dest="domain", default=[],
                      action=CheckDomain, nargs="*",
                      help=_("Enter domain type which you will be extending"))
     pol.add_argument("-u", "--user", dest="user", default=[],
-                     action=CheckUser, 
+                     action=CheckUser,
                      help=_("Enter SELinux user(s) which will transition to this domain"))
     pol.add_argument("-r", "--role", dest="role", default=[],
                      action=CheckRole,
                      help=_("Enter SELinux role(s) to which the administror domain will transition"))
-    pol.add_argument("-a", "--admin", dest="admin_domain",default=[],
+    pol.add_argument("-a", "--admin", dest="admin_domain", default=[],
                      action=CheckAdmin,
                      help=_("Enter domain(s) which this confined admin will administrate"))
     pol.add_argument("-n", "--name", dest="name",
@@ -566,29 +614,29 @@
     pol.add_argument("-T", "--test", dest="test", default=False, action="store_true",
                      help=argparse.SUPPRESS)
     pol.add_argument("-t", "--type", dest="types", default=[], nargs="*",
-                     action=CheckType, 
+                     action=CheckType,
                      help="Enter type(s) for which you will generate new definition and rule(s)")
     pol.add_argument("-p", "--path", dest="path", default=os.getcwd(),
                      help=_("path in which the generated policy files will be stored"))
-    pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default = [],
+    pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default=[],
                      help=_("path to which the confined processes will need to write"))
     cmdtype = pol.add_argument_group(_("Policy types which require a command"))
     cmdgroup = cmdtype.add_mutually_exclusive_group(required=False)
     cmdgroup.add_argument("--application", dest="policytype", const=USER,
-                       action="store_const",
-                       help=_("Generate '%s' policy") % poltype[USER])
+                          action="store_const",
+                          help=_("Generate '%s' policy") % poltype[USER])
     cmdgroup.add_argument("--cgi", dest="policytype", const=CGI,
-                       action="store_const",
-                       help=_("Generate '%s' policy") % poltype[CGI])
+                          action="store_const",
+                          help=_("Generate '%s' policy") % poltype[CGI])
     cmdgroup.add_argument("--dbus", dest="policytype", const=DBUS,
-                       action="store_const",
-                       help=_("Generate '%s' policy") % poltype[DBUS])
+                          action="store_const",
+                          help=_("Generate '%s' policy") % poltype[DBUS])
     cmdgroup.add_argument("--inetd", dest="policytype", const=INETD,
-                       action="store_const",
-                       help=_("Generate '%s' policy") % poltype[INETD])
+                          action="store_const",
+                          help=_("Generate '%s' policy") % poltype[INETD])
     cmdgroup.add_argument("--init", dest="policytype", const=DAEMON,
-                       action="store_const", default=DAEMON,
-                       help=_("Generate '%s' policy") % poltype[DAEMON])
+                          action="store_const", default=DAEMON,
+                          help=_("Generate '%s' policy") % poltype[DAEMON])
 
     type = pol.add_argument_group("Policy types which do not require a command")
     group = type.add_mutually_exclusive_group(required=False)
@@ -616,7 +664,7 @@
     group.add_argument("--x_user", dest="policytype", const=XUSER,
                        action="store_const",
                        help=_("Generate '%s' policy") % poltype[XUSER])
-    pol.add_argument("command",nargs="?", default=None,
+    pol.add_argument("command", nargs="?", default=None,
                      help=_("executable to confine"))
     pol.set_defaults(func=generate)
 
@@ -637,15 +685,15 @@
 
     try:
         if os.path.basename(sys.argv[0]) == "sepolgen":
-            args = parser.parse_args([ "generate" ] + sys.argv[1:])
+            args = parser.parse_args(["generate"] + sys.argv[1:])
         else:
             args = parser.parse_args()
         args.func(args)
         sys.exit(0)
-    except ValueError,e:
+    except ValueError, e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
         sys.exit(1)
-    except IOError,e:
+    except IOError, e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
         sys.exit(1)
     except KeyboardInterrupt:
diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
index 679725d..693c6fe 100644
--- a/policycoreutils/sepolicy/sepolicy/__init__.py
+++ b/policycoreutils/sepolicy/sepolicy/__init__.py
@@ -4,8 +4,9 @@
 # Author: Ryan Hallisey <rhallise@redhat.com>
 
 import _policy
-import selinux, glob
-PROGNAME="policycoreutils"
+import selinux
+import glob
+PROGNAME = "policycoreutils"
 import gettext
 import sepolgen.defaults as defaults
 import sepolgen.interfaces as interfaces
@@ -16,7 +17,7 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
@@ -27,7 +28,7 @@
 PORT = _policy.PORT
 USER = _policy.USER
 BOOLEAN = _policy.BOOLEAN
-TCLASS =  _policy.CLASS
+TCLASS = _policy.CLASS
 
 ALLOW = 'allow'
 AUDITALLOW = 'auditallow'
@@ -40,11 +41,13 @@
 TRANSITION = 'transition'
 ROLE_ALLOW = 'role_allow'
 
+
 def info(setype, name=None):
     dict_list = _policy.info(setype, name)
     return dict_list
 
-def search(types, info = {}):
+
+def search(types, info={}):
     seinfo = info
     valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW]
     for setype in types:
@@ -62,35 +65,38 @@
         dict_list = filter(lambda x: _dict_has_perms(x, perms), dict_list)
     return dict_list
 
-def get_conditionals(src,dest,tclass,perm):
+
+def get_conditionals(src, dest, tclass, perm):
     tdict = {}
     tlist = []
     if dest.endswith("_t"):
-        allows=search([ALLOW],{SOURCE:src,TARGET:dest,CLASS:tclass,PERMS:perm})
+        allows = search([ALLOW], {SOURCE: src, TARGET: dest, CLASS: tclass, PERMS: perm})
     else:
         # to include attribute
-        allows=search([ALLOW],{SOURCE:src,CLASS:tclass,PERMS:perm})
+        allows = search([ALLOW], {SOURCE: src, CLASS: tclass, PERMS: perm})
         for i in allows:
             if i['target'] == dest:
-                allows=[]
+                allows = []
                 allows.append(i)
     try:
         for i in map(lambda y: (y), filter(lambda x: set(perm).issubset(x[PERMS]) and x['boolean'], allows)):
-            tdict.update({'source':i['source'],'boolean':i['boolean']})
+            tdict.update({'source': i['source'], 'boolean': i['boolean']})
             if tdict not in tlist:
                 tlist.append(tdict)
-                tdict={}
+                tdict = {}
     except KeyError:
         return(tlist)
 
     return (tlist)
 
+
 def get_conditionals_format_text(cond):
     enabled = len(filter(lambda x: x['boolean'][0][1], cond)) > 0
     return _("-- Allowed %s [ %s ]") % (enabled, " || ".join(set(map(lambda x: "%s=%d" % (x['boolean'][0][0], x['boolean'][0][1]), cond))))
 
+
 def get_types_from_attribute(attribute):
-    return info(ATTRIBUTE,attribute)[0]["types"]
+    return info(ATTRIBUTE, attribute)[0]["types"]
 
 file_type_str = {}
 file_type_str["a"] = _("all files")
@@ -112,9 +118,10 @@
 trans_file_type_str["-l"] = "l"
 trans_file_type_str["-p"] = "p"
 
+
 def get_file_types(setype):
-    flist=[]
-    mpaths={}
+    flist = []
+    mpaths = {}
     for f in get_all_file_types():
         if f.startswith(gen_short_name(setype)):
             flist.append(f)
@@ -126,12 +133,13 @@
             mpaths[f] = []
     return mpaths
 
+
 def get_writable_files(setype):
     all_attributes = get_all_attributes()
     file_types = get_all_file_types()
     all_writes = []
     mpaths = {}
-    permlist = search([ALLOW],{'source':setype,  'permlist':['open', 'write'], 'class':'file'})
+    permlist = search([ALLOW], {'source': setype, 'permlist': ['open', 'write'], 'class': 'file'})
     if permlist == None or len(permlist) == 0:
         return mpaths
 
@@ -159,13 +167,17 @@
         try:
             mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]])
         except KeyError:
-            mpaths[f] = [] #{"regex":[],"paths":[]}
+            mpaths[f] = []  # {"regex":[],"paths":[]}
     return mpaths
 
-import os, re, sys
+import os
+import re
+import sys
+
+
 def find_file(reg):
     if os.path.exists(reg):
-        return [ reg ]
+        return [reg]
     try:
         pat = re.compile(r"%s$" % reg)
     except:
@@ -190,7 +202,8 @@
     except:
         return []
 
-def find_all_files(domain, exclude_list = []):
+
+def find_all_files(domain, exclude_list=[]):
     all_entrypoints = []
     executable_files = get_entrypoints(domain)
     for exe in executable_files.keys():
@@ -202,7 +215,9 @@
     return None
 
 #return all_entrypoints
-def find_entrypoint_path(exe, exclude_list = []):
+
+
+def find_entrypoint_path(exe, exclude_list=[]):
     fcdict = get_fcdict()
     try:
         if exe.endswith("_exec_t") and exe not in exclude_list:
@@ -213,40 +228,47 @@
         pass
     return None
 
+
 def read_file_equiv(edict, fc_path, modify):
-        fd = open(fc_path, "r")
-        fc = fd.readlines()
-        fd.close()
-        for e in fc:
-            f = e.split()
-            edict[f[0]] = { "equiv" : f[1], "modify" : modify }
-        return edict
+    fd = open(fc_path, "r")
+    fc = fd.readlines()
+    fd.close()
+    for e in fc:
+        f = e.split()
+        edict[f[0]] = {"equiv": f[1], "modify": modify}
+    return edict
 
-file_equiv_modified=None
-def get_file_equiv_modified(fc_path = selinux.selinux_file_context_path()):
-        global file_equiv_modified
-        if file_equiv_modified:
-                return file_equiv_modified
-        file_equiv_modified = {}
-        file_equiv_modified = read_file_equiv(file_equiv_modified, fc_path + ".subs", modify=True)
+file_equiv_modified = None
+
+
+def get_file_equiv_modified(fc_path=selinux.selinux_file_context_path()):
+    global file_equiv_modified
+    if file_equiv_modified:
         return file_equiv_modified
+    file_equiv_modified = {}
+    file_equiv_modified = read_file_equiv(file_equiv_modified, fc_path + ".subs", modify=True)
+    return file_equiv_modified
 
-file_equiv=None
-def get_file_equiv(fc_path = selinux.selinux_file_context_path()):
-        global file_equiv
-        if file_equiv:
-                return file_equiv
-        file_equiv = get_file_equiv_modified(fc_path)
-        file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify = False)
+file_equiv = None
+
+
+def get_file_equiv(fc_path=selinux.selinux_file_context_path()):
+    global file_equiv
+    if file_equiv:
         return file_equiv
+    file_equiv = get_file_equiv_modified(fc_path)
+    file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify=False)
+    return file_equiv
 
-local_files=None
-def get_local_file_paths(fc_path = selinux.selinux_file_context_path()):
+local_files = None
+
+
+def get_local_file_paths(fc_path=selinux.selinux_file_context_path()):
     global local_files
     if local_files:
         return local_files
-    local_files=[]
-    fd = open(fc_path+".local", "r")
+    local_files = []
+    fd = open(fc_path + ".local", "r")
     fc = fd.readlines()
     fd.close()
     for i in fc:
@@ -264,19 +286,21 @@
             pass
     return local_files
 
-fcdict=None
-def get_fcdict(fc_path = selinux.selinux_file_context_path()):
+fcdict = None
+
+
+def get_fcdict(fc_path=selinux.selinux_file_context_path()):
     global fcdict
     if fcdict:
         return fcdict
     fd = open(fc_path, "r")
     fc = fd.readlines()
     fd.close()
-    fd = open(fc_path+".homedirs", "r")
+    fd = open(fc_path + ".homedirs", "r")
     fc += fd.readlines()
     fd.close()
     fcdict = {}
-    fd = open(fc_path+".local", "r")
+    fd = open(fc_path + ".local", "r")
     fc += fd.readlines()
     fd.close()
 
@@ -292,45 +316,49 @@
             if t in fcdict:
                 fcdict[t]["regex"].append(rec[0])
             else:
-                fcdict[t] = { "regex": [ rec[0] ], "ftype": ftype}
+                fcdict[t] = {"regex": [rec[0]], "ftype": ftype}
         except:
             pass
 
-    fcdict["logfile"] = { "regex" : [ "all log files" ]}
-    fcdict["user_tmp_type"] = { "regex" : [ "all user tmp files" ]}
-    fcdict["user_home_type"] = { "regex" : [ "all user home files" ]}
-    fcdict["virt_image_type"] = { "regex" : [ "all virtual image files" ]}
-    fcdict["noxattrfs"] = { "regex" : [ "all files on file systems which do not support extended attributes" ]}
-    fcdict["sandbox_tmpfs_type"] = { "regex" : [ "all sandbox content in tmpfs file systems" ]}
-    fcdict["user_tmpfs_type"] = { "regex" : [ "all user content in tmpfs file systems" ]}
-    fcdict["file_type"] = { "regex" : [ "all files on the system" ]}
-    fcdict["samba_share_t"] = { "regex" : [ "use this label for random content that will be shared using samba" ]}
+    fcdict["logfile"] = {"regex": ["all log files"]}
+    fcdict["user_tmp_type"] = {"regex": ["all user tmp files"]}
+    fcdict["user_home_type"] = {"regex": ["all user home files"]}
+    fcdict["virt_image_type"] = {"regex": ["all virtual image files"]}
+    fcdict["noxattrfs"] = {"regex": ["all files on file systems which do not support extended attributes"]}
+    fcdict["sandbox_tmpfs_type"] = {"regex": ["all sandbox content in tmpfs file systems"]}
+    fcdict["user_tmpfs_type"] = {"regex": ["all user content in tmpfs file systems"]}
+    fcdict["file_type"] = {"regex": ["all files on the system"]}
+    fcdict["samba_share_t"] = {"regex": ["use this label for random content that will be shared using samba"]}
     return fcdict
 
+
 def get_transitions_into(setype):
     try:
-        return filter(lambda x: x["transtype"] == setype, search([TRANSITION],{ 'class':'process'}))
+        return filter(lambda x: x["transtype"] == setype, search([TRANSITION], {'class': 'process'}))
     except TypeError:
         pass
     return None
 
+
 def get_transitions(setype):
     try:
-        return search([TRANSITION],{'source':setype, 'class':'process'})
+        return search([TRANSITION], {'source': setype, 'class': 'process'})
     except TypeError:
         pass
     return None
 
+
 def get_file_transitions(setype):
     try:
-        return filter(lambda x: x['class'] != "process", search([TRANSITION],{'source':setype}))
+        return filter(lambda x: x['class'] != "process", search([TRANSITION], {'source': setype}))
     except TypeError:
         pass
     return None
 
+
 def get_boolean_rules(setype, boolean):
     boollist = []
-    permlist = search([ALLOW],{'source':setype })
+    permlist = search([ALLOW], {'source': setype})
     for p in permlist:
         if "boolean" in p:
             try:
@@ -341,21 +369,24 @@
                 pass
     return boollist
 
+
 def get_all_entrypoints():
     return get_types_from_attribute("entry_type")
 
+
 def get_entrypoint_types(setype):
     entrypoints = []
     try:
-        entrypoints = map(lambda x: x['target'],filter(lambda x: x['source'] == setype, search([ALLOW],{'source':setype,  'permlist':['entrypoint'], 'class':'file'})))
+        entrypoints = map(lambda x: x['target'], filter(lambda x: x['source'] == setype, search([ALLOW], {'source': setype, 'permlist': ['entrypoint'], 'class': 'file'})))
     except TypeError:
         pass
     return entrypoints
 
+
 def get_init_transtype(path):
     entrypoint = selinux.getfilecon(path)[1].split(":")[2]
     try:
-        entrypoints = filter(lambda x: x['target'] == entrypoint, search([TRANSITION],{'source':"init_t", 'class':'process'}))
+        entrypoints = filter(lambda x: x['target'] == entrypoint, search([TRANSITION], {'source': "init_t", 'class': 'process'}))
         if len(entrypoints) == 0:
             return None
         return entrypoints[0]["transtype"]
@@ -363,9 +394,10 @@
         pass
     return None
 
+
 def get_init_entrypoint(transtype):
     try:
-        entrypoints = filter(lambda x: x['transtype'] == transtype, search([TRANSITION],{'source':"init_t", 'class':'process'}))
+        entrypoints = filter(lambda x: x['transtype'] == transtype, search([TRANSITION], {'source': "init_t", 'class': 'process'}))
         if len(entrypoints) == 0:
             return None
         return entrypoints[0]["target"]
@@ -373,14 +405,16 @@
         pass
     return None
 
+
 def get_init_entrypoint_target(entrypoint):
     try:
-        entrypoints = map(lambda x: x['transtype'], search([TRANSITION],{'source':"init_t",  'target':entrypoint, 'class':'process'}))
+        entrypoints = map(lambda x: x['transtype'], search([TRANSITION], {'source': "init_t", 'target': entrypoint, 'class': 'process'}))
         return entrypoints[0]
     except TypeError:
         pass
     return None
 
+
 def get_entrypoints(setype):
     fcdict = get_fcdict()
     mpaths = {}
@@ -391,10 +425,11 @@
             mpaths[f] = []
     return mpaths
 
-def get_installed_policy(root = "/"):
+
+def get_installed_policy(root="/"):
     try:
         path = root + selinux.selinux_binary_policy_path()
-        policies = glob.glob ("%s.*" % path )
+        policies = glob.glob("%s.*" % path)
         policies.sort()
         return policies[-1]
     except:
@@ -402,6 +437,8 @@
     raise ValueError(_("No SELinux Policy installed"))
 
 methods = []
+
+
 def get_methods():
     global methods
     if len(methods) > 0:
@@ -423,39 +460,46 @@
     return methods
 
 all_types = None
+
+
 def get_all_types():
     global all_types
     if all_types == None:
         all_types = map(lambda x: x['name'], info(TYPE))
     return all_types
 
-user_types =  None
+user_types = None
+
+
 def get_user_types():
     global user_types
     if user_types == None:
-        user_types = info(ATTRIBUTE,"userdomain")[0]["types"]
+        user_types = info(ATTRIBUTE, "userdomain")[0]["types"]
     return user_types
 
 role_allows = None
-def get_all_role_allows():
-        global role_allows
-        if role_allows:
-                return role_allows
-        role_allows = {}
-        for r in search([ROLE_ALLOW]):
-                if r["source"] == "system_r" or r["target"] == "system_r":
-                        continue
-                if r["source"] in role_allows:
-                        role_allows[r["source"]].append(r["target"])
-                else:
-                        role_allows[r["source"]] = [ r["target"] ]
 
+
+def get_all_role_allows():
+    global role_allows
+    if role_allows:
         return role_allows
+    role_allows = {}
+    for r in search([ROLE_ALLOW]):
+        if r["source"] == "system_r" or r["target"] == "system_r":
+            continue
+        if r["source"] in role_allows:
+            role_allows[r["source"]].append(r["target"])
+        else:
+            role_allows[r["source"]] = [r["target"]]
+
+    return role_allows
+
 
 def get_all_entrypoint_domains():
     import re
     all_domains = []
-    types=get_all_types()
+    types = get_all_types()
     types.sort()
     for i in types:
         m = re.findall("(.*)%s" % "_exec_t$", i)
@@ -467,6 +511,7 @@
 portrecs = None
 portrecsbynum = None
 
+
 def gen_interfaces():
     import commands
     ifile = defaults.interface_info()
@@ -482,11 +527,12 @@
         raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
     print commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1]
 
+
 def gen_port_dict():
     global portrecs
     global portrecsbynum
     if portrecs:
-        return ( portrecs, portrecsbynum )
+        return (portrecs, portrecsbynum)
     portrecsbynum = {}
     portrecs = {}
     for i in info(PORT):
@@ -496,94 +542,111 @@
             port = "%s-%s" % (str(i['low']), str(i['high']))
 
         if (i['type'], i['protocol']) in portrecs:
-            portrecs [(i['type'], i['protocol'])].append(port)
+            portrecs[(i['type'], i['protocol'])].append(port)
         else:
-            portrecs [(i['type'], i['protocol'])] = [port]
+            portrecs[(i['type'], i['protocol'])] = [port]
 
         if 'range' in i:
-            portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'], i['range'])
+            portrecsbynum[(i['low'], i['high'], i['protocol'])] = (i['type'], i['range'])
         else:
-            portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'])
+            portrecsbynum[(i['low'], i['high'], i['protocol'])] = (i['type'])
 
-    return ( portrecs, portrecsbynum )
+    return (portrecs, portrecsbynum)
 
 all_domains = None
+
+
 def get_all_domains():
-        global all_domains
-        if not all_domains:
-            all_domains = info(ATTRIBUTE,"domain")[0]["types"]
-        return all_domains
+    global all_domains
+    if not all_domains:
+        all_domains = info(ATTRIBUTE, "domain")[0]["types"]
+    return all_domains
 
 roles = None
+
+
 def get_all_roles():
-        global roles
-        if roles:
-                return roles
-        roles = map(lambda x: x['name'], info(ROLE))
-        roles.remove("object_r")
-        roles.sort()
+    global roles
+    if roles:
         return roles
+    roles = map(lambda x: x['name'], info(ROLE))
+    roles.remove("object_r")
+    roles.sort()
+    return roles
 
 selinux_user_list = None
+
+
 def get_selinux_users():
     global selinux_user_list
     if not selinux_user_list:
         selinux_user_list = info(USER)
         for x in selinux_user_list:
-            x['range']="".join(x['range'].split(" "))
+            x['range'] = "".join(x['range'].split(" "))
     return selinux_user_list
 
 login_mappings = None
+
+
 def get_login_mappings():
     global login_mappings
     if login_mappings:
         return login_mappings
 
     fd = open(selinux.selinux_usersconf_path(), "r")
-    buf=fd.read()
+    buf = fd.read()
     fd.close()
     login_mappings = []
-    for b in  buf.split("\n"):
+    for b in buf.split("\n"):
         b = b.strip()
         if len(b) == 0 or b.startswith("#"):
             continue
         x = b.split(":")
-        login_mappings.append({ "name": x[0], "seuser": x[1], "mls":":".join(x[2:])})
+        login_mappings.append({"name": x[0], "seuser": x[1], "mls": ":".join(x[2:])})
     return login_mappings
 
+
 def get_all_users():
     users = map(lambda x: x['name'], get_selinux_users())
     users.sort()
     return users
 
 file_types = None
+
+
 def get_all_file_types():
-        global file_types
-        if file_types:
-                return file_types
-        file_types =  info(ATTRIBUTE,"file_type")[0]["types"]
-        file_types.sort()
+    global file_types
+    if file_types:
         return file_types
+    file_types = info(ATTRIBUTE, "file_type")[0]["types"]
+    file_types.sort()
+    return file_types
 
 port_types = None
+
+
 def get_all_port_types():
-        global port_types
-        if port_types:
-                return port_types
-        port_types =  info(ATTRIBUTE,"port_type")[0]["types"]
-        port_types.sort()
+    global port_types
+    if port_types:
         return port_types
+    port_types = info(ATTRIBUTE, "port_type")[0]["types"]
+    port_types.sort()
+    return port_types
 
 bools = None
-def get_all_bools():
-        global bools
-        if not bools:
-                bools = info(BOOLEAN)
-        return bools
 
-def prettyprint(f,trim):
+
+def get_all_bools():
+    global bools
+    if not bools:
+        bools = info(BOOLEAN)
+    return bools
+
+
+def prettyprint(f, trim):
     return " ".join(f[:-len(trim)].split("_"))
 
+
 def markup(f):
     return f
 
@@ -604,104 +667,108 @@
 DEFAULT_DIRS["/var/spool"] = "var_spool_t"
 DEFAULT_DIRS["/var/www"] = "content_t"
 
+
 def get_description(f, markup=markup):
 
     txt = "Set files with the %s type, if you want to " % markup(f)
 
     if f.endswith("_var_run_t"):
-        return txt +  "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t")
+        return txt + "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t")
     if f.endswith("_pid_t"):
-        return txt +  "store the %s files under the /run directory." % prettyprint(f, "_pid_t")
+        return txt + "store the %s files under the /run directory." % prettyprint(f, "_pid_t")
     if f.endswith("_var_lib_t"):
-        return txt +  "store the %s files under the /var/lib directory."  % prettyprint(f, "_var_lib_t")
+        return txt + "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t")
     if f.endswith("_var_t"):
-        return txt +  "store the %s files under the /var directory."  % prettyprint(f, "_var_lib_t")
+        return txt + "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t")
     if f.endswith("_var_spool_t"):
-        return txt +  "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
+        return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
     if f.endswith("_spool_t"):
-        return txt +  "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
+        return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
     if f.endswith("_cache_t") or f.endswith("_var_cache_t"):
-        return txt +  "store the files under the /var/cache directory."
+        return txt + "store the files under the /var/cache directory."
     if f.endswith("_keytab_t"):
-        return txt +  "treat the files as kerberos keytab files."
+        return txt + "treat the files as kerberos keytab files."
     if f.endswith("_lock_t"):
-        return txt +  "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t")
+        return txt + "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f, "_lock_t")
     if f.endswith("_log_t"):
-        return txt +  "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t")
+        return txt + "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f, "_log_t")
     if f.endswith("_config_t"):
-        return txt +  "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t")
+        return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f, "_config_t")
     if f.endswith("_conf_t"):
-        return txt +  "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t")
+        return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f, "_conf_t")
     if f.endswith("_exec_t"):
-        return txt +  "transition an executable to the %s_t domain." % f[:-len("_exec_t")]
+        return txt + "transition an executable to the %s_t domain." % f[:-len("_exec_t")]
     if f.endswith("_cgi_content_t"):
-        return txt +  "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t")
+        return txt + "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t")
     if f.endswith("_rw_content_t"):
-        return txt +  "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t")
+        return txt + "treat the files as %s read/write content." % prettyprint(f, "_rw_content_t")
     if f.endswith("_rw_t"):
-        return txt +  "treat the files as %s read/write content." % prettyprint(f,"_rw_t")
+        return txt + "treat the files as %s read/write content." % prettyprint(f, "_rw_t")
     if f.endswith("_write_t"):
-        return txt +  "treat the files as %s read/write content." % prettyprint(f,"_write_t")
+        return txt + "treat the files as %s read/write content." % prettyprint(f, "_write_t")
     if f.endswith("_db_t"):
-        return txt +  "treat the files as %s database content." % prettyprint(f,"_db_t")
+        return txt + "treat the files as %s database content." % prettyprint(f, "_db_t")
     if f.endswith("_ra_content_t"):
-        return txt +  "treat the files as %s read/append content." % prettyprint(f,"_ra_conten_t")
+        return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_conten_t")
     if f.endswith("_cert_t"):
-        return txt +  "treat the files as %s certificate data." % prettyprint(f,"_cert_t")
+        return txt + "treat the files as %s certificate data." % prettyprint(f, "_cert_t")
     if f.endswith("_key_t"):
-        return txt +  "treat the files as %s key data." % prettyprint(f,"_key_t")
+        return txt + "treat the files as %s key data." % prettyprint(f, "_key_t")
 
     if f.endswith("_secret_t"):
-        return txt +  "treat the files as %s secret data." % prettyprint(f,"_key_t")
+        return txt + "treat the files as %s secret data." % prettyprint(f, "_key_t")
 
     if f.endswith("_ra_t"):
-        return txt +  "treat the files as %s read/append content." % prettyprint(f,"_ra_t")
+        return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_t")
 
     if f.endswith("_ro_t"):
-        return txt +  "treat the files as %s read/only content." % prettyprint(f,"_ro_t")
+        return txt + "treat the files as %s read/only content." % prettyprint(f, "_ro_t")
 
     if f.endswith("_modules_t"):
-        return txt +  "treat the files as %s modules." % prettyprint(f, "_modules_t")
+        return txt + "treat the files as %s modules." % prettyprint(f, "_modules_t")
 
     if f.endswith("_content_t"):
-        return txt +  "treat the files as %s content." % prettyprint(f, "_content_t")
+        return txt + "treat the files as %s content." % prettyprint(f, "_content_t")
 
     if f.endswith("_state_t"):
-        return txt +  "treat the files as %s state data." % prettyprint(f, "_state_t")
+        return txt + "treat the files as %s state data." % prettyprint(f, "_state_t")
 
     if f.endswith("_files_t"):
-        return txt +  "treat the files as %s content." % prettyprint(f, "_files_t")
+        return txt + "treat the files as %s content." % prettyprint(f, "_files_t")
 
     if f.endswith("_file_t"):
-        return txt +  "treat the files as %s content." % prettyprint(f, "_file_t")
+        return txt + "treat the files as %s content." % prettyprint(f, "_file_t")
 
     if f.endswith("_data_t"):
-        return txt +  "treat the files as %s content." % prettyprint(f, "_data_t")
+        return txt + "treat the files as %s content." % prettyprint(f, "_data_t")
 
     if f.endswith("_file_t"):
-        return txt +  "treat the data as %s content." % prettyprint(f, "_file_t")
+        return txt + "treat the data as %s content." % prettyprint(f, "_file_t")
 
     if f.endswith("_tmp_t"):
-        return txt +  "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
+        return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
     if f.endswith("_etc_t"):
-        return txt +  "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
+        return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
     if f.endswith("_home_t"):
-        return txt +  "store %s files in the users home directory." % prettyprint(f, "_home_t")
+        return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t")
     if f.endswith("_tmpfs_t"):
-        return txt +  "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t")
+        return txt + "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t")
     if f.endswith("_unit_file_t"):
-        return txt +  "treat files as a systemd unit file."
+        return txt + "treat files as a systemd unit file."
     if f.endswith("_htaccess_t"):
-        return txt +  "treat the file as a %s access file." % prettyprint(f, "_htaccess_t")
+        return txt + "treat the file as a %s access file." % prettyprint(f, "_htaccess_t")
 
-    return txt +  "treat the files as %s data." % prettyprint(f,"_t")
+    return txt + "treat the files as %s data." % prettyprint(f, "_t")
 
 all_attributes = None
+
+
 def get_all_attributes():
-        global all_attributes
-        if not all_attributes:
-                all_attributes = map(lambda x: x['name'], info(ATTRIBUTE))
-        return all_attributes
+    global all_attributes
+    if not all_attributes:
+        all_attributes = map(lambda x: x['name'], info(ATTRIBUTE))
+    return all_attributes
+
 
 def policy(policy_file):
     global all_domains
@@ -734,12 +801,14 @@
     if selinux.is_selinux_enabled() == 1:
         raise e
 
+
 def _dict_has_perms(dict, perms):
     for perm in perms:
         if perm not in dict[PERMS]:
             return False
     return True
 
+
 def gen_short_name(setype):
     all_domains = get_all_domains()
     if setype.endswith("_t"):
@@ -747,20 +816,21 @@
     else:
         domainname = setype
     if domainname + "_t" not in all_domains:
-        raise  ValueError("domain %s_t does not exist" % domainname)
-    if domainname[-1]=='d':
+        raise ValueError("domain %s_t does not exist" % domainname)
+    if domainname[-1] == 'd':
         short_name = domainname[:-1] + "_"
     else:
         short_name = domainname + "_"
     return (domainname, short_name)
 
+
 def get_bools(setype):
     bools = []
     domainbools = []
     domainname, short_name = gen_short_name(setype)
-    for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, search([ALLOW],{'source' : setype}))):
+    for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, search([ALLOW], {'source': setype}))):
         for b in i:
-            if not isinstance(b,tuple):
+            if not isinstance(b, tuple):
                 continue
             try:
                 enabled = selinux.security_get_boolean_active(b[0])
@@ -771,10 +841,12 @@
                     domainbools.append((b[0], enabled))
             else:
                 if (b[0], enabled) not in bools and (b[0], not enabled) not in bools:
-                    bools.append((b[0],enabled))
+                    bools.append((b[0], enabled))
     return (domainbools, bools)
 
 booleans = None
+
+
 def get_all_booleans():
     global booleans
     if not booleans:
@@ -783,6 +855,8 @@
 
 booleans_dict = None
 import gzip
+
+
 def policy_xml(path="/usr/share/selinux/devel/policy.xml"):
     try:
         fd = gzip.open(path)
@@ -794,36 +868,38 @@
         fd.close()
     return buf
 
+
 def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"):
-        global booleans_dict
-        if booleans_dict:
-            return booleans_dict
-        import xml.etree.ElementTree
-        import re
-        booleans_dict = {}
-        try:
-                tree = xml.etree.ElementTree.fromstring(policy_xml(path))
-                for l in  tree.findall("layer"):
-                        for m in  l.findall("module"):
-                                for b in  m.findall("tunable"):
-                                        desc = b.find("desc").find("p").text.strip("\n")
-                                        desc = re.sub("\n", " ", desc)
-                                        booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
-                                for b in  m.findall("bool"):
-                                        desc = b.find("desc").find("p").text.strip("\n")
-                                        desc = re.sub("\n", " ", desc)
-                                        booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
-                        for i in  tree.findall("bool"):
-                                desc = i.find("desc").find("p").text.strip("\n")
-                                desc = re.sub("\n", " ", desc)
-                                booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
-                for i in  tree.findall("tunable"):
-                        desc = i.find("desc").find("p").text.strip("\n")
-                        desc = re.sub("\n", " ", desc)
-                        booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
-        except IOError, e:
-                pass
+    global booleans_dict
+    if booleans_dict:
         return booleans_dict
+    import xml.etree.ElementTree
+    import re
+    booleans_dict = {}
+    try:
+        tree = xml.etree.ElementTree.fromstring(policy_xml(path))
+        for l in tree.findall("layer"):
+            for m in l.findall("module"):
+                for b in m.findall("tunable"):
+                    desc = b.find("desc").find("p").text.strip("\n")
+                    desc = re.sub("\n", " ", desc)
+                    booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
+                for b in m.findall("bool"):
+                    desc = b.find("desc").find("p").text.strip("\n")
+                    desc = re.sub("\n", " ", desc)
+                    booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
+            for i in tree.findall("bool"):
+                desc = i.find("desc").find("p").text.strip("\n")
+                desc = re.sub("\n", " ", desc)
+                booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
+        for i in tree.findall("tunable"):
+            desc = i.find("desc").find("p").text.strip("\n")
+            desc = re.sub("\n", " ", desc)
+            booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc)
+    except IOError, e:
+        pass
+    return booleans_dict
+
 
 def boolean_category(boolean):
     booleans_dict = gen_bool_dict()
@@ -832,13 +908,15 @@
     else:
         return _("unknown")
 
+
 def boolean_desc(boolean):
-       booleans_dict = gen_bool_dict()
-       if boolean in booleans_dict:
-              return _(booleans_dict[boolean][2])
-       else:
-           desc = boolean.split("_")
-           return "Allow %s to %s" % (desc[0], " ".join(desc[1:]))
+    booleans_dict = gen_bool_dict()
+    if boolean in booleans_dict:
+        return _(booleans_dict[boolean][2])
+    else:
+        desc = boolean.split("_")
+        return "Allow %s to %s" % (desc[0], " ".join(desc[1:]))
+
 
 def get_os_version():
     os_version = ""
@@ -852,14 +930,15 @@
         os_version = ""
 
     if os_version[0:2] == "fc":
-        os_version = "Fedora"+os_version[2:]
+        os_version = "Fedora" + os_version[2:]
     elif os_version[0:2] == "el":
-        os_version = "RHEL"+os_version[2:]
+        os_version = "RHEL" + os_version[2:]
     else:
         os_version = ""
 
     return os_version
 
+
 def reinit():
     global all_attributes
     global all_domains
@@ -888,7 +967,7 @@
     bools = None
     fcdict = None
     file_types = None
-    local_files=None
+    local_files = None
     methods = None
     methods = None
     portrecs = None
diff --git a/policycoreutils/sepolicy/sepolicy/booleans.py b/policycoreutils/sepolicy/sepolicy/booleans.py
index 9003652..56bef26 100644
--- a/policycoreutils/sepolicy/sepolicy/booleans.py
+++ b/policycoreutils/sepolicy/sepolicy/booleans.py
@@ -1,5 +1,5 @@
 #! /usr/bin/python -Es
-# Copyright (C) 2012 Red Hat 
+# Copyright (C) 2012 Red Hat
 # see file 'COPYING' for use and warranty information
 #
 # setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,22 +16,25 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #                                        02111-1307  USA
 #
-#  
-import sepolicy, sys
-search=sepolicy.search
-info=sepolicy.info
+#
+import sepolicy
+import sys
+search = sepolicy.search
+info = sepolicy.info
+
 
 def expand_attribute(attribute):
     try:
         return info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
     except RuntimeError:
-        return [ attribute ]
+        return [attribute]
+
 
 def get_types(src, tclass, perm):
-    allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
+    allows = search([sepolicy.ALLOW], {sepolicy.SOURCE: src, sepolicy.CLASS: tclass, sepolicy.PERMS: perm})
     if not allows:
         raise TypeError("The %s type is not allowed to %s any types" % (src, ",".join(perm)))
 
diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py
index 9b9a09a..9939c23 100755
--- a/policycoreutils/sepolicy/sepolicy/communicate.py
+++ b/policycoreutils/sepolicy/sepolicy/communicate.py
@@ -1,5 +1,5 @@
 #! /usr/bin/python -Es
-# Copyright (C) 2012 Red Hat 
+# Copyright (C) 2012 Red Hat
 # see file 'COPYING' for use and warranty information
 #
 # setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,13 +16,16 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #                                        02111-1307  USA
 #
-#  
-import sepolicy, sys
-search=sepolicy.search
-info=sepolicy.info
+#
+import sepolicy
+import sys
+search = sepolicy.search
+info = sepolicy.info
+
+
 def usage(parser, msg):
     parser.print_help()
 
@@ -35,10 +38,11 @@
     try:
         return info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
     except RuntimeError:
-        return [ attribute ]
+        return [attribute]
+
 
 def get_types(src, tclass, perm):
-    allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
+    allows = search([sepolicy.ALLOW], {sepolicy.SOURCE: src, sepolicy.CLASS: tclass, sepolicy.PERMS: perm})
     if not allows:
         raise ValueError("The %s type is not allowed to %s any types" % (src, ",".join(perm)))
 
@@ -46,4 +50,3 @@
     for l in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)):
         tlist = tlist + expand_attribute(l)
     return tlist
-
diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py
index 4858582..a92783a 100644
--- a/policycoreutils/sepolicy/sepolicy/generate.py
+++ b/policycoreutils/sepolicy/sepolicy/generate.py
@@ -21,7 +21,9 @@
 #                                        02111-1307  USA
 #
 #
-import os, sys, stat
+import os
+import sys
+import stat
 import re
 import sepolicy
 from sepolicy import get_all_types, get_all_attributes, get_all_roles
@@ -49,7 +51,7 @@
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -58,20 +60,22 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 def get_rpm_nvr_from_header(hdr):
     'Given an RPM header return the package NVR as a string'
-    name    = hdr['name']
+    name = hdr['name']
     version = hdr['version']
     release = hdr['release']
-    release_version = version+"-"+release.split(".")[0]
+    release_version = version + "-" + release.split(".")[0]
     os_version = release.split(".")[1]
 
-    return [name,release_version,os_version]
+    return [name, release_version, os_version]
+
 
 def get_rpm_nvr_list(package):
     try:
@@ -88,6 +92,7 @@
 
     return nvr
 
+
 def get_all_ports():
     dict = {}
     for p in sepolicy.info(sepolicy.PORT):
@@ -95,9 +100,10 @@
                 p['type'] == "port_t" or \
                 p['type'] == "hi_reserved_port_t":
             continue
-        dict[(p['low'], p['high'], p['protocol'])]=(p['type'], p['range'])
+        dict[(p['low'], p['high'], p['protocol'])] = (p['type'], p['range'])
     return dict
 
+
 def get_all_users():
     users = map(lambda x: x['name'], sepolicy.info(sepolicy.USER))
     users.remove("system_u")
@@ -126,7 +132,7 @@
 RUSER = 11
 NEWTYPE = 12
 
-poltype={}
+poltype = {}
 poltype[DAEMON] = _("Standard Init Daemon")
 poltype[DBUS] = _("DBUS System Daemon")
 poltype[INETD] = _("Internet Services Daemon")
@@ -141,6 +147,7 @@
 poltype[RUSER] = _("Confined Root Administrator Role")
 poltype[NEWTYPE] = _("Module information for a new type")
 
+
 def get_poltype_desc():
     keys = poltype.keys()
     keys.sort()
@@ -148,1118 +155,1126 @@
     for k in keys:
         msg += "%2s: %s\n" % (k, poltype[k])
     return msg
-        
-APPLICATIONS = [ DAEMON, DBUS, INETD, USER, CGI ]
-USERS = [ XUSER, TUSER, LUSER, AUSER, RUSER]
+
+APPLICATIONS = [DAEMON, DBUS, INETD, USER, CGI]
+USERS = [XUSER, TUSER, LUSER, AUSER, RUSER]
+
 
 def verify_ports(ports):
     if ports == "":
         return []
-    max_port=2**16
+    max_port = 2 ** 16
     try:
         temp = []
         for a in ports.split(","):
-            r =  a.split("-")
+            r = a.split("-")
             if len(r) > 2:
-                raise  ValueError
+                raise ValueError
             if len(r) == 1:
-                begin = int (r[0])
-                end = int (r[0])
+                begin = int(r[0])
+                end = int(r[0])
             else:
-                begin = int (r[0])
-                end = int (r[1])
+                begin = int(r[0])
+                end = int(r[1])
 
                 if begin > end:
-                    raise  ValueError
+                    raise ValueError
 
             for p in range(begin, end + 1):
                 if p < 1 or p > max_port:
-                    raise  ValueError
+                    raise ValueError
                 temp.append(p)
         return temp
     except ValueError:
-        raise  ValueError(_("Ports must be numbers or ranges of numbers from 1 to %d " % max_port ))
+        raise ValueError(_("Ports must be numbers or ranges of numbers from 1 to %d " % max_port))
+
 
 class policy:
 
-	def __init__(self, name, type):
-                self.rpms = []
-                self.ports = []
-                self.all_roles = get_all_roles()
-                self.types = []
+    def __init__(self, name, type):
+        self.rpms = []
+        self.ports = []
+        self.all_roles = get_all_roles()
+        self.types = []
 
-                if type not in poltype:
-                    raise ValueError(_("You must enter a valid policy type"))
+        if type not in poltype:
+            raise ValueError(_("You must enter a valid policy type"))
 
-		if not name:
-                    raise ValueError(_("You must enter a name for your policy module for your '%s'.") % poltype[type])
-                try:
-                    self.ports = get_all_ports()
-                except ValueError, e:
-                    print "Can not get port types, must be root for this information"
-                except RuntimeError, e:
-                    print "Can not get port types", e
+        if not name:
+            raise ValueError(_("You must enter a name for your policy module for your '%s'.") % poltype[type])
+        try:
+            self.ports = get_all_ports()
+        except ValueError, e:
+            print "Can not get port types, must be root for this information"
+        except RuntimeError, e:
+            print "Can not get port types", e
 
-                self.symbols = {}
-                self.symbols["openlog"] = "set_use_kerberos(True)"
-                self.symbols["openlog"] = "set_use_kerb_rcache(True)"
-                self.symbols["openlog"] = "set_use_syslog(True)"
-                self.symbols["gethostby"] = "set_use_resolve(True)"
-                self.symbols["getaddrinfo"] = "set_use_resolve(True)"
-                self.symbols["getnameinfo"] = "set_use_resolve(True)"
-                self.symbols["krb"] = "set_use_kerberos(True)"
-                self.symbols["gss_accept_sec_context"] = "set_manage_krb5_rcache(True)"
-                self.symbols["krb5_verify_init_creds"] = "set_manage_krb5_rcache(True)"
-                self.symbols["krb5_rd_req"] = "set_manage_krb5_rcache(True)"
-                self.symbols["__syslog_chk"] = "set_use_syslog(True)"
-                self.symbols["getpwnam"] = "set_use_uid(True)"
-                self.symbols["getpwuid"] = "set_use_uid(True)"
-                self.symbols["dbus_"] = "set_use_dbus(True)"
-                self.symbols["pam_"] = "set_use_pam(True)"
-                self.symbols["pam_"] = "set_use_audit(True)"
-                self.symbols["fork"] = "add_process('fork')"
-                self.symbols["transition"] = "add_process('transition')"
-                self.symbols["sigchld"] = "add_process('sigchld')"
-                self.symbols["sigkill"] = "add_process('sigkill')"
-                self.symbols["sigstop"] = "add_process('sigstop')"
-                self.symbols["signull"] = "add_process('signull')"
-                self.symbols["ptrace"] = "add_process('ptrace')"
-                self.symbols["getsched"] = "add_process('getsched')"
-                self.symbols["setsched"] = "add_process('setsched')"
-                self.symbols["getsession"] = "add_process('getsession')"
-                self.symbols["getpgid"] = "add_process('getpgid')"
-                self.symbols["setpgid"] = "add_process('setpgid')"
-                self.symbols["getcap"] = "add_process('getcap')"
-                self.symbols["setcap"] = "add_process('setcap')"
-                self.symbols["share"] = "add_process('share')"
-                self.symbols["getattr"] = "add_process('getattr')"
-                self.symbols["setexec"] = "add_process('setexec')"
-                self.symbols["setfscreate"] = "add_process('setfscreate')"
-                self.symbols["noatsecure"] = "add_process('noatsecure')"
-                self.symbols["siginh"] = "add_process('siginh')"
-                self.symbols["kill"] = "add_process('signal_perms')"
-                self.symbols["setrlimit"] = "add_process('setrlimit')"
-                self.symbols["rlimitinh"] = "add_process('rlimitinh')"
-                self.symbols["dyntransition"] = "add_process('dyntransition')"
-                self.symbols["setcurrent"] = "add_process('setcurrent')"
-                self.symbols["execmem"] = "add_process('execmem')"
-                self.symbols["execstack"] = "add_process('execstack')"
-                self.symbols["execheap"] = "add_process('execheap')"
-                self.symbols["setkeycreate"] = "add_process('setkeycreate')"
-                self.symbols["setsockcreate"] = "add_process('setsockcreate')"
+        self.symbols = {}
+        self.symbols["openlog"] = "set_use_kerberos(True)"
+        self.symbols["openlog"] = "set_use_kerb_rcache(True)"
+        self.symbols["openlog"] = "set_use_syslog(True)"
+        self.symbols["gethostby"] = "set_use_resolve(True)"
+        self.symbols["getaddrinfo"] = "set_use_resolve(True)"
+        self.symbols["getnameinfo"] = "set_use_resolve(True)"
+        self.symbols["krb"] = "set_use_kerberos(True)"
+        self.symbols["gss_accept_sec_context"] = "set_manage_krb5_rcache(True)"
+        self.symbols["krb5_verify_init_creds"] = "set_manage_krb5_rcache(True)"
+        self.symbols["krb5_rd_req"] = "set_manage_krb5_rcache(True)"
+        self.symbols["__syslog_chk"] = "set_use_syslog(True)"
+        self.symbols["getpwnam"] = "set_use_uid(True)"
+        self.symbols["getpwuid"] = "set_use_uid(True)"
+        self.symbols["dbus_"] = "set_use_dbus(True)"
+        self.symbols["pam_"] = "set_use_pam(True)"
+        self.symbols["pam_"] = "set_use_audit(True)"
+        self.symbols["fork"] = "add_process('fork')"
+        self.symbols["transition"] = "add_process('transition')"
+        self.symbols["sigchld"] = "add_process('sigchld')"
+        self.symbols["sigkill"] = "add_process('sigkill')"
+        self.symbols["sigstop"] = "add_process('sigstop')"
+        self.symbols["signull"] = "add_process('signull')"
+        self.symbols["ptrace"] = "add_process('ptrace')"
+        self.symbols["getsched"] = "add_process('getsched')"
+        self.symbols["setsched"] = "add_process('setsched')"
+        self.symbols["getsession"] = "add_process('getsession')"
+        self.symbols["getpgid"] = "add_process('getpgid')"
+        self.symbols["setpgid"] = "add_process('setpgid')"
+        self.symbols["getcap"] = "add_process('getcap')"
+        self.symbols["setcap"] = "add_process('setcap')"
+        self.symbols["share"] = "add_process('share')"
+        self.symbols["getattr"] = "add_process('getattr')"
+        self.symbols["setexec"] = "add_process('setexec')"
+        self.symbols["setfscreate"] = "add_process('setfscreate')"
+        self.symbols["noatsecure"] = "add_process('noatsecure')"
+        self.symbols["siginh"] = "add_process('siginh')"
+        self.symbols["kill"] = "add_process('signal_perms')"
+        self.symbols["setrlimit"] = "add_process('setrlimit')"
+        self.symbols["rlimitinh"] = "add_process('rlimitinh')"
+        self.symbols["dyntransition"] = "add_process('dyntransition')"
+        self.symbols["setcurrent"] = "add_process('setcurrent')"
+        self.symbols["execmem"] = "add_process('execmem')"
+        self.symbols["execstack"] = "add_process('execstack')"
+        self.symbols["execheap"] = "add_process('execheap')"
+        self.symbols["setkeycreate"] = "add_process('setkeycreate')"
+        self.symbols["setsockcreate"] = "add_process('setsockcreate')"
 
-                self.symbols["chown"] = "add_capability('chown')"
-                self.symbols["dac_override"] = "add_capability('dac_override')"
-                self.symbols["dac_read_search"] = "add_capability('dac_read_search')"
-                self.symbols["fowner"] = "add_capability('fowner')"
-                self.symbols["fsetid"] = "add_capability('fsetid')"
-                self.symbols["setgid"] = "add_capability('setgid')"
-                self.symbols["setegid"] = "add_capability('setgid')"
-                self.symbols["setresgid"] = "add_capability('setgid')"
-                self.symbols["setregid"] = "add_capability('setgid')"
-                self.symbols["setresuid"] = "add_capability('setuid')"
-                self.symbols["setuid"] = "add_capability('setuid')"
-                self.symbols["seteuid"] = "add_capability('setuid')"
-                self.symbols["setreuid"] = "add_capability('setuid')"
-                self.symbols["setresuid"] = "add_capability('setuid')"
-                self.symbols["setpcap"] = "add_capability('setpcap')"
-                self.symbols["linux_immutable"] = "add_capability('linux_immutable')"
-                self.symbols["net_bind_service"] = "add_capability('net_bind_service')"
-                self.symbols["net_broadcast"] = "add_capability('net_broadcast')"
-                self.symbols["net_admin"] = "add_capability('net_admin')"
-                self.symbols["net_raw"] = "add_capability('net_raw')"
-                self.symbols["ipc_lock"] = "add_capability('ipc_lock')"
-                self.symbols["ipc_owner"] = "add_capability('ipc_owner')"
-                self.symbols["sys_module"] = "add_capability('sys_module')"
-                self.symbols["sys_rawio"] = "add_capability('sys_rawio')"
-                self.symbols["chroot"] = "add_capability('sys_chroot')"
-                self.symbols["sys_chroot"] = "add_capability('sys_chroot')"
-                self.symbols["sys_ptrace"] = "add_capability('sys_ptrace')"
-                self.symbols["sys_pacct"] = "add_capability('sys_pacct')"
-                self.symbols["mount"] = "add_capability('sys_admin')"
-                self.symbols["unshare"] = "add_capability('sys_admin')"
-                self.symbols["sys_admin"] = "add_capability('sys_admin')"
-                self.symbols["sys_boot"] = "add_capability('sys_boot')"
-                self.symbols["sys_nice"] = "add_capability('sys_nice')"
-                self.symbols["sys_resource"] = "add_capability('sys_resource')"
-                self.symbols["sys_time"] = "add_capability('sys_time')"
-                self.symbols["sys_tty_config"] = "add_capability('sys_tty_config')"
-                self.symbols["mknod"] = "add_capability('mknod')"
-                self.symbols["lease"] = "add_capability('lease')"
-                self.symbols["audit_write"] = "add_capability('audit_write')"
-                self.symbols["audit_control"] = "add_capability('audit_control')"
-                self.symbols["setfcap"] = "add_capability('setfcap')"
+        self.symbols["chown"] = "add_capability('chown')"
+        self.symbols["dac_override"] = "add_capability('dac_override')"
+        self.symbols["dac_read_search"] = "add_capability('dac_read_search')"
+        self.symbols["fowner"] = "add_capability('fowner')"
+        self.symbols["fsetid"] = "add_capability('fsetid')"
+        self.symbols["setgid"] = "add_capability('setgid')"
+        self.symbols["setegid"] = "add_capability('setgid')"
+        self.symbols["setresgid"] = "add_capability('setgid')"
+        self.symbols["setregid"] = "add_capability('setgid')"
+        self.symbols["setresuid"] = "add_capability('setuid')"
+        self.symbols["setuid"] = "add_capability('setuid')"
+        self.symbols["seteuid"] = "add_capability('setuid')"
+        self.symbols["setreuid"] = "add_capability('setuid')"
+        self.symbols["setresuid"] = "add_capability('setuid')"
+        self.symbols["setpcap"] = "add_capability('setpcap')"
+        self.symbols["linux_immutable"] = "add_capability('linux_immutable')"
+        self.symbols["net_bind_service"] = "add_capability('net_bind_service')"
+        self.symbols["net_broadcast"] = "add_capability('net_broadcast')"
+        self.symbols["net_admin"] = "add_capability('net_admin')"
+        self.symbols["net_raw"] = "add_capability('net_raw')"
+        self.symbols["ipc_lock"] = "add_capability('ipc_lock')"
+        self.symbols["ipc_owner"] = "add_capability('ipc_owner')"
+        self.symbols["sys_module"] = "add_capability('sys_module')"
+        self.symbols["sys_rawio"] = "add_capability('sys_rawio')"
+        self.symbols["chroot"] = "add_capability('sys_chroot')"
+        self.symbols["sys_chroot"] = "add_capability('sys_chroot')"
+        self.symbols["sys_ptrace"] = "add_capability('sys_ptrace')"
+        self.symbols["sys_pacct"] = "add_capability('sys_pacct')"
+        self.symbols["mount"] = "add_capability('sys_admin')"
+        self.symbols["unshare"] = "add_capability('sys_admin')"
+        self.symbols["sys_admin"] = "add_capability('sys_admin')"
+        self.symbols["sys_boot"] = "add_capability('sys_boot')"
+        self.symbols["sys_nice"] = "add_capability('sys_nice')"
+        self.symbols["sys_resource"] = "add_capability('sys_resource')"
+        self.symbols["sys_time"] = "add_capability('sys_time')"
+        self.symbols["sys_tty_config"] = "add_capability('sys_tty_config')"
+        self.symbols["mknod"] = "add_capability('mknod')"
+        self.symbols["lease"] = "add_capability('lease')"
+        self.symbols["audit_write"] = "add_capability('audit_write')"
+        self.symbols["audit_control"] = "add_capability('audit_control')"
+        self.symbols["setfcap"] = "add_capability('setfcap')"
 
-		self.DEFAULT_DIRS = {}
-		self.DEFAULT_DIRS["/etc"] = ["etc_rw", [], etc_rw];
-		self.DEFAULT_DIRS["/tmp"] = ["tmp", [], tmp];
-		self.DEFAULT_DIRS["rw"] = ["rw", [], rw];
-		self.DEFAULT_DIRS["/usr/lib/systemd/system"] = ["unit_file", [], unit_file];
-		self.DEFAULT_DIRS["/lib/systemd/system"] = ["unit_file", [], unit_file];
-		self.DEFAULT_DIRS["/etc/systemd/system"] = ["unit_file", [], unit_file];
-		self.DEFAULT_DIRS["/var/cache"] = ["var_cache", [], var_cache];
-		self.DEFAULT_DIRS["/var/lib"] = ["var_lib", [], var_lib];
-		self.DEFAULT_DIRS["/var/log"] = ["var_log", [], var_log];
-		self.DEFAULT_DIRS["/var/run"] = ["var_run", [], var_run];
-		self.DEFAULT_DIRS["/var/spool"] = ["var_spool", [], var_spool];
+        self.DEFAULT_DIRS = {}
+        self.DEFAULT_DIRS["/etc"] = ["etc_rw", [], etc_rw]
+        self.DEFAULT_DIRS["/tmp"] = ["tmp", [], tmp]
+        self.DEFAULT_DIRS["rw"] = ["rw", [], rw]
+        self.DEFAULT_DIRS["/usr/lib/systemd/system"] = ["unit_file", [], unit_file]
+        self.DEFAULT_DIRS["/lib/systemd/system"] = ["unit_file", [], unit_file]
+        self.DEFAULT_DIRS["/etc/systemd/system"] = ["unit_file", [], unit_file]
+        self.DEFAULT_DIRS["/var/cache"] = ["var_cache", [], var_cache]
+        self.DEFAULT_DIRS["/var/lib"] = ["var_lib", [], var_lib]
+        self.DEFAULT_DIRS["/var/log"] = ["var_log", [], var_log]
+        self.DEFAULT_DIRS["/var/run"] = ["var_run", [], var_run]
+        self.DEFAULT_DIRS["/var/spool"] = ["var_spool", [], var_spool]
 
-		self.DEFAULT_EXT = {}
-		self.DEFAULT_EXT["_tmp_t"] = tmp;
-		self.DEFAULT_EXT["_unit_file_t"] = unit_file;
-		self.DEFAULT_EXT["_var_cache_t"] = var_cache;
-		self.DEFAULT_EXT["_var_lib_t"] = var_lib;
-		self.DEFAULT_EXT["_var_log_t"] = var_log;
-		self.DEFAULT_EXT["_var_run_t"] = var_run;
-		self.DEFAULT_EXT["_var_spool_t"] = var_spool;
-		self.DEFAULT_EXT["_port_t"] = network;
+        self.DEFAULT_EXT = {}
+        self.DEFAULT_EXT["_tmp_t"] = tmp
+        self.DEFAULT_EXT["_unit_file_t"] = unit_file
+        self.DEFAULT_EXT["_var_cache_t"] = var_cache
+        self.DEFAULT_EXT["_var_lib_t"] = var_lib
+        self.DEFAULT_EXT["_var_log_t"] = var_log
+        self.DEFAULT_EXT["_var_run_t"] = var_run
+        self.DEFAULT_EXT["_var_spool_t"] = var_spool
+        self.DEFAULT_EXT["_port_t"] = network
 
-                self.DEFAULT_KEYS=["/etc", "/var/cache", "/var/log", "/tmp", "rw", "/var/lib", "/var/run", "/var/spool", "/etc/systemd/system", "/usr/lib/systemd/system", "/lib/systemd/system" ]
+        self.DEFAULT_KEYS = ["/etc", "/var/cache", "/var/log", "/tmp", "rw", "/var/lib", "/var/run", "/var/spool", "/etc/systemd/system", "/usr/lib/systemd/system", "/lib/systemd/system"]
 
-		self.DEFAULT_TYPES = (\
-( self.generate_daemon_types, self.generate_daemon_rules), \
-( self.generate_dbusd_types, self.generate_dbusd_rules), \
-( self.generate_inetd_types, self.generate_inetd_rules), \
-( self.generate_cgi_types, self.generate_cgi_rules), \
-( self.generate_sandbox_types, self.generate_sandbox_rules), \
-( self.generate_userapp_types, self.generate_userapp_rules), \
-( self.generate_existing_user_types, self.generate_existing_user_rules), \
-( self.generate_min_login_user_types, self.generate_login_user_rules), \
-( self.generate_x_login_user_types, self.generate_x_login_user_rules), \
-( self.generate_login_user_types, self.generate_login_user_rules), \
-( self.generate_admin_user_types, self.generate_login_user_rules), \
-( self.generate_root_user_types, self.generate_root_user_rules), \
-( self.generate_new_types, self.generate_new_rules))
-                if not re.match(r"^[a-zA-Z0-9-_]+$", name):
-                    raise ValueError(_("Name must be alpha numberic with no spaces. Consider using option \"-n MODULENAME\""))
+        self.DEFAULT_TYPES = (
+            (self.generate_daemon_types, self.generate_daemon_rules),
+            (self.generate_dbusd_types, self.generate_dbusd_rules),
+            (self.generate_inetd_types, self.generate_inetd_rules),
+            (self.generate_cgi_types, self.generate_cgi_rules),
+            (self.generate_sandbox_types, self.generate_sandbox_rules),
+            (self.generate_userapp_types, self.generate_userapp_rules),
+            (self.generate_existing_user_types, self.generate_existing_user_rules),
+            (self.generate_min_login_user_types, self.generate_login_user_rules),
+            (self.generate_x_login_user_types, self.generate_x_login_user_rules),
+            (self.generate_login_user_types, self.generate_login_user_rules),
+            (self.generate_admin_user_types, self.generate_login_user_rules),
+            (self.generate_root_user_types, self.generate_root_user_rules),
+            (self.generate_new_types, self.generate_new_rules))
+        if not re.match(r"^[a-zA-Z0-9-_]+$", name):
+            raise ValueError(_("Name must be alpha numberic with no spaces. Consider using option \"-n MODULENAME\""))
 
-		if type == CGI:
-			self.name = "httpd_%s_script" % name
-		else:
-			self.name = name
+        if type == CGI:
+            self.name = "httpd_%s_script" % name
+        else:
+            self.name = name
 
-                self.file_name = name
+        self.file_name = name
 
-                self.capabilities = []
-                self.processes = []
-		self.type = type
-		self.initscript = ""
-                self.program = None
-		self.in_tcp = [False, False, False, []]
-		self.in_udp = [False, False, False, []]
-		self.out_tcp = [False, False, False, []]
-		self.out_udp = [False, False, False, []]
-		self.use_resolve = False
-		self.use_tmp = False
-		self.use_uid = False
-		self.use_syslog = False
-		self.use_kerberos = False
-		self.manage_krb5_rcache = False
-		self.use_pam = False
-		self.use_dbus = False
-		self.use_audit = False
-		self.use_etc = self.type not in [ EUSER, NEWTYPE ]
-		self.use_localization = self.type not in [ EUSER, NEWTYPE ]
-		self.use_fd = self.type not in [ EUSER, NEWTYPE ]
-		self.use_terminal = False
-		self.use_mail = False
-		self.booleans = {}
-		self.files = {}
-		self.dirs = {}
-                self.found_tcp_ports=[]
-                self.found_udp_ports=[]
-                self.need_tcp_type=False
-                self.need_udp_type=False
-		self.admin_domains = []
-		self.existing_domains = []
-		self.transition_domains = []
-		self.transition_users = []
-                self.roles = []
+        self.capabilities = []
+        self.processes = []
+        self.type = type
+        self.initscript = ""
+        self.program = None
+        self.in_tcp = [False, False, False, []]
+        self.in_udp = [False, False, False, []]
+        self.out_tcp = [False, False, False, []]
+        self.out_udp = [False, False, False, []]
+        self.use_resolve = False
+        self.use_tmp = False
+        self.use_uid = False
+        self.use_syslog = False
+        self.use_kerberos = False
+        self.manage_krb5_rcache = False
+        self.use_pam = False
+        self.use_dbus = False
+        self.use_audit = False
+        self.use_etc = self.type not in [EUSER, NEWTYPE]
+        self.use_localization = self.type not in [EUSER, NEWTYPE]
+        self.use_fd = self.type not in [EUSER, NEWTYPE]
+        self.use_terminal = False
+        self.use_mail = False
+        self.booleans = {}
+        self.files = {}
+        self.dirs = {}
+        self.found_tcp_ports = []
+        self.found_udp_ports = []
+        self.need_tcp_type = False
+        self.need_udp_type = False
+        self.admin_domains = []
+        self.existing_domains = []
+        self.transition_domains = []
+        self.transition_users = []
+        self.roles = []
 
-        def __isnetset(self, l):
-            return l[ALL] or l[RESERVED] or l[UNRESERVED] or len(l[PORTS]) > 0
+    def __isnetset(self, l):
+        return l[ALL] or l[RESERVED] or l[UNRESERVED] or len(l[PORTS]) > 0
 
-        def set_admin_domains(self, admin_domains):
-            self.admin_domains = admin_domains
+    def set_admin_domains(self, admin_domains):
+        self.admin_domains = admin_domains
 
-        def set_existing_domains(self, existing_domains):
-            self.existing_domains = existing_domains
+    def set_existing_domains(self, existing_domains):
+        self.existing_domains = existing_domains
 
-        def set_admin_roles(self, roles):
-            self.roles = roles
+    def set_admin_roles(self, roles):
+        self.roles = roles
 
-        def set_transition_domains(self, transition_domains):
-            self.transition_domains = transition_domains
+    def set_transition_domains(self, transition_domains):
+        self.transition_domains = transition_domains
 
-        def set_transition_users(self, transition_users):
-            self.transition_users = transition_users
+    def set_transition_users(self, transition_users):
+        self.transition_users = transition_users
 
-        def use_in_udp(self):
-            return self.__isnetset(self.in_udp)
+    def use_in_udp(self):
+        return self.__isnetset(self.in_udp)
 
-        def use_out_udp(self):
-            return self.__isnetset(self.out_udp)
+    def use_out_udp(self):
+        return self.__isnetset(self.out_udp)
 
-        def use_udp(self):
-            return self.use_in_udp() or self.use_out_udp()
+    def use_udp(self):
+        return self.use_in_udp() or self.use_out_udp()
 
-        def use_in_tcp(self):
-            return self.__isnetset(self.in_tcp)
+    def use_in_tcp(self):
+        return self.__isnetset(self.in_tcp)
 
-        def use_out_tcp(self):
-            return self.__isnetset(self.out_tcp)
+    def use_out_tcp(self):
+        return self.__isnetset(self.out_tcp)
 
-        def use_tcp(self):
-            return self.use_in_tcp() or self.use_out_tcp()
+    def use_tcp(self):
+        return self.use_in_tcp() or self.use_out_tcp()
 
-        def use_network(self):
-            return self.use_tcp() or self.use_udp()
+    def use_network(self):
+        return self.use_tcp() or self.use_udp()
 
-        def find_port(self, port, protocol="tcp"):
-            for begin,end,p in self.ports.keys():
-                if port >= begin and port <= end and protocol == p:
-                    return self.ports[begin, end, protocol]
-            return  None
+    def find_port(self, port, protocol="tcp"):
+        for begin, end, p in self.ports.keys():
+            if port >= begin and port <= end and protocol == p:
+                return self.ports[begin, end, protocol]
+        return None
 
-	def set_program(self, program):
-                if self.type not in APPLICATIONS:
-                    raise ValueError(_("User Role types can not be assigned executables."))
+    def set_program(self, program):
+        if self.type not in APPLICATIONS:
+            raise ValueError(_("User Role types can not be assigned executables."))
 
-		self.program = program
+        self.program = program
 
-	def set_init_script(self, initscript):
-                if self.type != DAEMON:
-                    raise ValueError(_("Only Daemon apps can use an init script.."))
+    def set_init_script(self, initscript):
+        if self.type != DAEMON:
+            raise ValueError(_("Only Daemon apps can use an init script.."))
 
-		self.initscript = initscript
+        self.initscript = initscript
 
-	def set_in_tcp(self, all, reserved, unreserved, ports):
-		self.in_tcp = [ all, reserved, unreserved, verify_ports(ports)]
+    def set_in_tcp(self, all, reserved, unreserved, ports):
+        self.in_tcp = [all, reserved, unreserved, verify_ports(ports)]
 
-	def set_in_udp(self, all, reserved, unreserved, ports):
-		self.in_udp = [ all, reserved, unreserved, verify_ports(ports)]
+    def set_in_udp(self, all, reserved, unreserved, ports):
+        self.in_udp = [all, reserved, unreserved, verify_ports(ports)]
 
-	def set_out_tcp(self, all, ports):
-		self.out_tcp = [ all , False, False, verify_ports(ports) ]
+    def set_out_tcp(self, all, ports):
+        self.out_tcp = [all, False, False, verify_ports(ports)]
 
-	def set_out_udp(self, all, ports):
-		self.out_udp = [ all , False, False, verify_ports(ports) ]
+    def set_out_udp(self, all, ports):
+        self.out_udp = [all, False, False, verify_ports(ports)]
 
-	def set_use_resolve(self, val):
-		if val != True and val != False:
-			raise  ValueError(_("use_resolve must be a boolean value "))
+    def set_use_resolve(self, val):
+        if val != True and val != False:
+            raise ValueError(_("use_resolve must be a boolean value "))
 
-		self.use_resolve = val
+        self.use_resolve = val
 
-	def set_use_syslog(self, val):
-		if val != True and val != False:
-			raise  ValueError(_("use_syslog must be a boolean value "))
+    def set_use_syslog(self, val):
+        if val != True and val != False:
+            raise ValueError(_("use_syslog must be a boolean value "))
 
-		self.use_syslog = val
+        self.use_syslog = val
 
-	def set_use_kerberos(self, val):
-		if val != True and val != False:
-			raise  ValueError(_("use_kerberos must be a boolean value "))
+    def set_use_kerberos(self, val):
+        if val != True and val != False:
+            raise ValueError(_("use_kerberos must be a boolean value "))
 
-		self.use_kerberos = val
+        self.use_kerberos = val
 
-	def set_manage_krb5_rcache(self, val):
-		if val != True and val != False:
-			raise  ValueError(_("manage_krb5_rcache must be a boolean value "))
+    def set_manage_krb5_rcache(self, val):
+        if val != True and val != False:
+            raise ValueError(_("manage_krb5_rcache must be a boolean value "))
 
-		self.manage_krb5_rcache = val
+        self.manage_krb5_rcache = val
 
-	def set_use_pam(self, val):
-		self.use_pam = val == True
+    def set_use_pam(self, val):
+        self.use_pam = val == True
 
-	def set_use_dbus(self, val):
-		self.use_dbus = val == True
+    def set_use_dbus(self, val):
+        self.use_dbus = val == True
 
-	def set_use_audit(self, val):
-		self.use_audit = val == True
+    def set_use_audit(self, val):
+        self.use_audit = val == True
 
-	def set_use_etc(self, val):
-		self.use_etc = val == True
+    def set_use_etc(self, val):
+        self.use_etc = val == True
 
-	def set_use_localization(self, val):
-		self.use_localization = val == True
+    def set_use_localization(self, val):
+        self.use_localization = val == True
 
-	def set_use_fd(self, val):
-		self.use_fd = val == True
+    def set_use_fd(self, val):
+        self.use_fd = val == True
 
-	def set_use_terminal(self, val):
-		self.use_terminal = val == True
+    def set_use_terminal(self, val):
+        self.use_terminal = val == True
 
-	def set_use_mail(self, val):
-		self.use_mail = val == True
+    def set_use_mail(self, val):
+        self.use_mail = val == True
 
-	def set_use_tmp(self, val):
-            if self.type in USERS:
-                raise ValueError(_("USER Types automatically get a tmp type"))
+    def set_use_tmp(self, val):
+        if self.type in USERS:
+            raise ValueError(_("USER Types automatically get a tmp type"))
 
-            if val:
-		self.DEFAULT_DIRS["/tmp"][1].append("/tmp");
-            else:
-		self.DEFAULT_DIRS["/tmp"][1]=[]
+        if val:
+            self.DEFAULT_DIRS["/tmp"][1].append("/tmp")
+        else:
+            self.DEFAULT_DIRS["/tmp"][1] = []
 
-	def set_use_uid(self, val):
-		self.use_uid = val == True
+    def set_use_uid(self, val):
+        self.use_uid = val == True
 
-	def generate_uid_rules(self):
-                if self.use_uid:
-                    return re.sub("TEMPLATETYPE", self.name, executable.te_uid_rules)
-                else:
-                    return ""
+    def generate_uid_rules(self):
+        if self.use_uid:
+            return re.sub("TEMPLATETYPE", self.name, executable.te_uid_rules)
+        else:
+            return ""
 
-	def generate_syslog_rules(self):
-                if self.use_syslog:
-                    return re.sub("TEMPLATETYPE", self.name, executable.te_syslog_rules)
-                else:
-                    return ""
+    def generate_syslog_rules(self):
+        if self.use_syslog:
+            return re.sub("TEMPLATETYPE", self.name, executable.te_syslog_rules)
+        else:
+            return ""
 
-	def generate_resolve_rules(self):
-                if self.use_resolve:
-                    return re.sub("TEMPLATETYPE", self.name, executable.te_resolve_rules)
-                else:
-                    return ""
+    def generate_resolve_rules(self):
+        if self.use_resolve:
+            return re.sub("TEMPLATETYPE", self.name, executable.te_resolve_rules)
+        else:
+            return ""
 
-	def generate_kerberos_rules(self):
-                if self.use_kerberos:
-                    return re.sub("TEMPLATETYPE", self.name, executable.te_kerberos_rules)
-                else:
-                    return ""
+    def generate_kerberos_rules(self):
+        if self.use_kerberos:
+            return re.sub("TEMPLATETYPE", self.name, executable.te_kerberos_rules)
+        else:
+            return ""
 
-	def generate_manage_krb5_rcache_rules(self):
-                if self.manage_krb5_rcache:
-                    return re.sub("TEMPLATETYPE", self.name, executable.te_manage_krb5_rcache_rules)
-                else:
-                    return ""
+    def generate_manage_krb5_rcache_rules(self):
+        if self.manage_krb5_rcache:
+            return re.sub("TEMPLATETYPE", self.name, executable.te_manage_krb5_rcache_rules)
+        else:
+            return ""
 
-	def generate_pam_rules(self):
-                newte =""
-                if self.use_pam:
-                    newte = re.sub("TEMPLATETYPE", self.name, executable.te_pam_rules)
-                return newte
+    def generate_pam_rules(self):
+        newte = ""
+        if self.use_pam:
+            newte = re.sub("TEMPLATETYPE", self.name, executable.te_pam_rules)
+        return newte
 
-	def generate_audit_rules(self):
-                newte =""
-                if self.use_audit:
-                    newte = re.sub("TEMPLATETYPE", self.name, executable.te_audit_rules)
-                return newte
+    def generate_audit_rules(self):
+        newte = ""
+        if self.use_audit:
+            newte = re.sub("TEMPLATETYPE", self.name, executable.te_audit_rules)
+        return newte
 
-	def generate_etc_rules(self):
-                newte =""
-                if self.use_etc:
-                    newte = re.sub("TEMPLATETYPE", self.name, executable.te_etc_rules)
-                return newte
+    def generate_etc_rules(self):
+        newte = ""
+        if self.use_etc:
+            newte = re.sub("TEMPLATETYPE", self.name, executable.te_etc_rules)
+        return newte
 
-	def generate_fd_rules(self):
-                newte =""
-                if self.use_fd:
-                    newte = re.sub("TEMPLATETYPE", self.name, executable.te_fd_rules)
-                return newte
+    def generate_fd_rules(self):
+        newte = ""
+        if self.use_fd:
+            newte = re.sub("TEMPLATETYPE", self.name, executable.te_fd_rules)
+        return newte
 
-	def generate_localization_rules(self):
-                newte =""
-                if self.use_localization:
-                    newte = re.sub("TEMPLATETYPE", self.name, executable.te_localization_rules)
-                return newte
+    def generate_localization_rules(self):
+        newte = ""
+        if self.use_localization:
+            newte = re.sub("TEMPLATETYPE", self.name, executable.te_localization_rules)
+        return newte
 
-	def generate_dbus_rules(self):
-                newte =""
-                if self.type != DBUS and self.use_dbus:
-                    newte = re.sub("TEMPLATETYPE", self.name, executable.te_dbus_rules)
-                return newte
+    def generate_dbus_rules(self):
+        newte = ""
+        if self.type != DBUS and self.use_dbus:
+            newte = re.sub("TEMPLATETYPE", self.name, executable.te_dbus_rules)
+        return newte
 
-	def generate_mail_rules(self):
-                newte =""
-                if self.use_mail:
-                    newte = re.sub("TEMPLATETYPE", self.name, executable.te_mail_rules)
-                return newte
+    def generate_mail_rules(self):
+        newte = ""
+        if self.use_mail:
+            newte = re.sub("TEMPLATETYPE", self.name, executable.te_mail_rules)
+        return newte
 
-        def generate_network_action(self, protocol, action, port_name):
-            line = ""
-            method = "corenet_%s_%s_%s" % (protocol, action, port_name)
-            if method in sepolicy.get_methods():
-                line = "%s(%s_t)\n" % (method, self.name)
-            else:
-                line = """
+    def generate_network_action(self, protocol, action, port_name):
+        line = ""
+        method = "corenet_%s_%s_%s" % (protocol, action, port_name)
+        if method in sepolicy.get_methods():
+            line = "%s(%s_t)\n" % (method, self.name)
+        else:
+            line = """
 gen_require(`
     type %s_t;
 ')
 allow %s_t %s_t:%s_socket name_%s;
 """ % (port_name, self.name, port_name, protocol, action)
-            return line
+        return line
 
-	def generate_network_types(self):
-            for i in self.in_tcp[PORTS]:
-                rec = self.find_port(int(i), "tcp")
-                if rec == None:
-                    self.need_tcp_type = True;
-                else:
-                    port_name = rec[0][:-2]
-                    line = self.generate_network_action("tcp", "bind", port_name)
+    def generate_network_types(self):
+        for i in self.in_tcp[PORTS]:
+            rec = self.find_port(int(i), "tcp")
+            if rec == None:
+                self.need_tcp_type = True
+            else:
+                port_name = rec[0][:-2]
+                line = self.generate_network_action("tcp", "bind", port_name)
 #                   line = "corenet_tcp_bind_%s(%s_t)\n" % (port_name, self.name)
-                    if line not in self.found_tcp_ports:
-                        self.found_tcp_ports.append(line)
+                if line not in self.found_tcp_ports:
+                    self.found_tcp_ports.append(line)
 
-            for i in self.out_tcp[PORTS]:
-                rec = self.find_port(int(i), "tcp")
-                if rec == None:
-                    self.need_tcp_type = True;
-                else:
-                    port_name = rec[0][:-2]
-                    line = self.generate_network_action("tcp", "connect", port_name)
+        for i in self.out_tcp[PORTS]:
+            rec = self.find_port(int(i), "tcp")
+            if rec == None:
+                self.need_tcp_type = True
+            else:
+                port_name = rec[0][:-2]
+                line = self.generate_network_action("tcp", "connect", port_name)
 #                   line = "corenet_tcp_connect_%s(%s_t)\n" % (port_name, self.name)
-                    if line not in self.found_tcp_ports:
-                        self.found_tcp_ports.append(line)
+                if line not in self.found_tcp_ports:
+                    self.found_tcp_ports.append(line)
 
-            for i in self.in_udp[PORTS]:
-                rec = self.find_port(int(i),"udp")
-                if rec == None:
-                    self.need_udp_type = True;
-                else:
-                    port_name = rec[0][:-2]
-                    line = self.generate_network_action("udp", "bind", port_name)
+        for i in self.in_udp[PORTS]:
+            rec = self.find_port(int(i), "udp")
+            if rec == None:
+                self.need_udp_type = True
+            else:
+                port_name = rec[0][:-2]
+                line = self.generate_network_action("udp", "bind", port_name)
 #                   line = "corenet_udp_bind_%s(%s_t)\n" % (port_name, self.name)
-                    if line not in self.found_udp_ports:
-                        self.found_udp_ports.append(line)
+                if line not in self.found_udp_ports:
+                    self.found_udp_ports.append(line)
 
-            if self.need_udp_type == True or self.need_tcp_type == True:
-                return re.sub("TEMPLATETYPE", self.name, network.te_types)
-            return ""
+        if self.need_udp_type == True or self.need_tcp_type == True:
+            return re.sub("TEMPLATETYPE", self.name, network.te_types)
+        return ""
 
-	def __find_path(self, file):
-            for d in self.DEFAULT_DIRS:
-                if file.find(d) == 0:
-                    self.DEFAULT_DIRS[d][1].append(file)
-                    return self.DEFAULT_DIRS[d]
-            self.DEFAULT_DIRS["rw"][1].append(file)
-            return self.DEFAULT_DIRS["rw"]
+    def __find_path(self, file):
+        for d in self.DEFAULT_DIRS:
+            if file.find(d) == 0:
+                self.DEFAULT_DIRS[d][1].append(file)
+                return self.DEFAULT_DIRS[d]
+        self.DEFAULT_DIRS["rw"][1].append(file)
+        return self.DEFAULT_DIRS["rw"]
 
-	def add_capability(self, capability):
-            if capability not in self.capabilities:
-                self.capabilities.append(capability)
+    def add_capability(self, capability):
+        if capability not in self.capabilities:
+            self.capabilities.append(capability)
 
-	def set_types(self, types):
-            self.types = types
+    def set_types(self, types):
+        self.types = types
 
-	def add_process(self, process):
-            if process not in self.processes:
-                self.processes.append(process)
+    def add_process(self, process):
+        if process not in self.processes:
+            self.processes.append(process)
 
-	def add_boolean(self, name, description):
-                self.booleans[name] = description
+    def add_boolean(self, name, description):
+        self.booleans[name] = description
 
-	def add_file(self, file):
-		self.files[file] = self.__find_path(file)
+    def add_file(self, file):
+        self.files[file] = self.__find_path(file)
 
-	def add_dir(self, file):
-		self.dirs[file] = self.__find_path(file)
+    def add_dir(self, file):
+        self.dirs[file] = self.__find_path(file)
 
-	def generate_capabilities(self):
-            newte = ""
-            self.capabilities.sort()
-            if len(self.capabilities) > 0:
-                newte = "allow %s_t self:capability { %s };\n" % (self.name, " ".join(self.capabilities))
-            return newte
+    def generate_capabilities(self):
+        newte = ""
+        self.capabilities.sort()
+        if len(self.capabilities) > 0:
+            newte = "allow %s_t self:capability { %s };\n" % (self.name, " ".join(self.capabilities))
+        return newte
 
-	def generate_process(self):
-            newte = ""
-            self.processes.sort()
-            if len(self.processes) > 0:
-                newte = "allow %s_t self:process { %s };\n" % (self.name, " ".join(self.processes))
-            return newte
+    def generate_process(self):
+        newte = ""
+        self.processes.sort()
+        if len(self.processes) > 0:
+            newte = "allow %s_t self:process { %s };\n" % (self.name, " ".join(self.processes))
+        return newte
 
+    def generate_network_rules(self):
+        newte = ""
+        if self.use_network():
+            newte = "\n"
 
-	def generate_network_rules(self):
-		newte = ""
-		if self.use_network():
-                    newte = "\n"
+            newte += re.sub("TEMPLATETYPE", self.name, network.te_network)
 
-                    newte += re.sub("TEMPLATETYPE", self.name, network.te_network)
+            if self.use_tcp():
+                newte += "\n"
+                newte += re.sub("TEMPLATETYPE", self.name, network.te_tcp)
 
-                    if self.use_tcp():
-                        newte += "\n"
-                        newte += re.sub("TEMPLATETYPE", self.name, network.te_tcp)
+                if self.use_in_tcp():
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_tcp)
 
-                        if self.use_in_tcp():
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_tcp)
+                    if self.need_tcp_type and len(self.in_tcp[PORTS]) > 0:
+                        newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_tcp)
 
-                            if self.need_tcp_type and len(self.in_tcp[PORTS]) > 0:
-                                newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_tcp)
+                if self.need_tcp_type and len(self.out_tcp[PORTS]) > 0:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_need_port_tcp)
 
-                        if self.need_tcp_type and len(self.out_tcp[PORTS]) > 0:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_out_need_port_tcp)
+                if self.in_tcp[ALL]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_tcp)
+                if self.in_tcp[RESERVED]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_tcp)
+                if self.in_tcp[UNRESERVED]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_tcp)
 
+                if self.out_tcp[ALL]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_all_ports_tcp)
+                if self.out_tcp[RESERVED]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_reserved_ports_tcp)
+                if self.out_tcp[UNRESERVED]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_unreserved_ports_tcp)
 
-                        if self.in_tcp[ALL]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_tcp)
-                        if self.in_tcp[RESERVED]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_tcp)
-                        if self.in_tcp[UNRESERVED]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_tcp)
+                for i in self.found_tcp_ports:
+                    newte += i
 
-                        if self.out_tcp[ALL]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_out_all_ports_tcp)
-                        if self.out_tcp[RESERVED]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_out_reserved_ports_tcp)
-                        if self.out_tcp[UNRESERVED]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_out_unreserved_ports_tcp)
+            if self.use_udp():
+                newte += "\n"
+                newte += re.sub("TEMPLATETYPE", self.name, network.te_udp)
 
-                        for i in self.found_tcp_ports:
-                            newte += i
+                if self.need_udp_type:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_udp)
+                if self.use_in_udp():
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_udp)
+                if self.in_udp[ALL]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_udp)
+                if self.in_udp[RESERVED]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_udp)
+                if self.in_udp[UNRESERVED]:
+                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_udp)
 
-                    if self.use_udp():
-                        newte += "\n"
-                        newte += re.sub("TEMPLATETYPE", self.name, network.te_udp)
+                for i in self.found_udp_ports:
+                    newte += i
+        return newte
 
-                        if self.need_udp_type:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_udp)
-                        if self.use_in_udp():
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_udp)
-                        if self.in_udp[ALL]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_udp)
-                        if self.in_udp[RESERVED]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_udp)
-                        if self.in_udp[UNRESERVED]:
-                            newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_udp)
+    def generate_transition_rules(self):
+        newte = ""
+        for app in self.transition_domains:
+            tmp = re.sub("TEMPLATETYPE", self.name, user.te_transition_rules)
+            newte += re.sub("APPLICATION", app, tmp)
 
-                        for i in self.found_udp_ports:
-                            newte += i
-		return newte
+        if self.type == USER:
+            for u in self.transition_users:
+                temp = re.sub("TEMPLATETYPE", self.name, executable.te_run_rules)
+                newte += re.sub("USER", u.split("_u")[0], temp)
 
-        def generate_transition_rules(self):
-            newte = ""
-            for app in self.transition_domains:
-                tmp = re.sub("TEMPLATETYPE", self.name, user.te_transition_rules)
-                newte += re.sub("APPLICATION", app, tmp)
+        return newte
 
-            if self.type == USER:
-                for u in self.transition_users:
-                    temp =  re.sub("TEMPLATETYPE", self.name, executable.te_run_rules)
-                    newte += re.sub("USER", u.split("_u")[0], temp)
-
-            return newte
-
-        def generate_admin_rules(self):
-            newte = ""
-            if self.type == EUSER:
-                for d in self.existing_domains:
-                    name = d.split("_t")[0]
-                    role = name + "_r"
-                    for app in self.admin_domains:
-                        tmp = re.sub("TEMPLATETYPE", name, user.te_admin_domain_rules)
-                        if role not in self.all_roles:
-                            tmp = re.sub(role, "system_r", tmp)
-                            
-                        
-                        newte += re.sub("APPLICATION", app, tmp)
-
-                return newte 
-
-            if self.type == RUSER:
-                newte += re.sub("TEMPLATETYPE", self.name, user.te_admin_rules)
-
+    def generate_admin_rules(self):
+        newte = ""
+        if self.type == EUSER:
+            for d in self.existing_domains:
+                name = d.split("_t")[0]
+                role = name + "_r"
                 for app in self.admin_domains:
-                    tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_domain_rules)
+                    tmp = re.sub("TEMPLATETYPE", name, user.te_admin_domain_rules)
+                    if role not in self.all_roles:
+                        tmp = re.sub(role, "system_r", tmp)
+
                     newte += re.sub("APPLICATION", app, tmp)
 
-                for u in self.transition_users:
-                    role = u.split("_u")[0]
-
-                    if (role + "_r") in self.all_roles:
-                        tmp =  re.sub("TEMPLATETYPE", self.name, user.te_admin_trans_rules)
-                        newte += re.sub("USER", role, tmp)
-
             return newte
 
-	def generate_dbus_if(self):
-                newif = ""
-                if self.use_dbus:
-                    newif = re.sub("TEMPLATETYPE", self.name, executable.if_dbus_rules)
-                return newif
+        if self.type == RUSER:
+            newte += re.sub("TEMPLATETYPE", self.name, user.te_admin_rules)
 
-        def generate_sandbox_if(self):
-            newif = ""
-            if self.type != SANDBOX:
-                return newif
-            newif = re.sub("TEMPLATETYPE", self.name, executable.if_sandbox_rules)
+            for app in self.admin_domains:
+                tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_domain_rules)
+                newte += re.sub("APPLICATION", app, tmp)
+
+            for u in self.transition_users:
+                role = u.split("_u")[0]
+
+                if (role + "_r") in self.all_roles:
+                    tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_trans_rules)
+                    newte += re.sub("USER", role, tmp)
+
+        return newte
+
+    def generate_dbus_if(self):
+        newif = ""
+        if self.use_dbus:
+            newif = re.sub("TEMPLATETYPE", self.name, executable.if_dbus_rules)
+        return newif
+
+    def generate_sandbox_if(self):
+        newif = ""
+        if self.type != SANDBOX:
             return newif
+        newif = re.sub("TEMPLATETYPE", self.name, executable.if_sandbox_rules)
+        return newif
 
+    def generate_admin_if(self):
+        newif = ""
+        newtypes = ""
+        if self.initscript != "":
+            newtypes += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin_types)
+            newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin)
+        for d in self.DEFAULT_KEYS:
+            if len(self.DEFAULT_DIRS[d][1]) > 0:
+                newtypes += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_types)
+                newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_rules)
 
-        def generate_admin_if(self):
-            newif = ""
-            newtypes = ""
-            if self.initscript != "":
-                newtypes += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin_types)
-                newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin)
-            for d in self.DEFAULT_KEYS:
-                if len(self.DEFAULT_DIRS[d][1]) > 0:
-                    newtypes += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_types)
-                    newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_rules)
+        if newif != "":
+            ret = re.sub("TEMPLATETYPE", self.name, executable.if_begin_admin)
+            ret += newtypes
 
-            if newif != "":
-                ret = re.sub("TEMPLATETYPE", self.name, executable.if_begin_admin)
-                ret += newtypes
+            ret += re.sub("TEMPLATETYPE", self.name, executable.if_middle_admin)
+            ret += newif
+            ret += re.sub("TEMPLATETYPE", self.name, executable.if_end_admin)
+            return ret
 
-                ret += re.sub("TEMPLATETYPE", self.name, executable.if_middle_admin)
-                ret += newif
-                ret += re.sub("TEMPLATETYPE", self.name, executable.if_end_admin)
-                return ret
+        return ""
 
-            return ""
+    def generate_cgi_types(self):
+        return re.sub("TEMPLATETYPE", self.file_name, executable.te_cgi_types)
 
-	def generate_cgi_types(self):
-		return re.sub("TEMPLATETYPE", self.file_name, executable.te_cgi_types)
+    def generate_sandbox_types(self):
+        return re.sub("TEMPLATETYPE", self.file_name, executable.te_sandbox_types)
 
-	def generate_sandbox_types(self):
-		return re.sub("TEMPLATETYPE", self.file_name, executable.te_sandbox_types)
+    def generate_userapp_types(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_types)
 
-	def generate_userapp_types(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_types)
+    def generate_inetd_types(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_types)
 
-	def generate_inetd_types(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_types)
+    def generate_dbusd_types(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_types)
 
-	def generate_dbusd_types(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_types)
+    def generate_min_login_user_types(self):
+        return re.sub("TEMPLATETYPE", self.name, user.te_min_login_user_types)
 
-	def generate_min_login_user_types(self):
-		return re.sub("TEMPLATETYPE", self.name, user.te_min_login_user_types)
+    def generate_login_user_types(self):
+        return re.sub("TEMPLATETYPE", self.name, user.te_login_user_types)
 
-	def generate_login_user_types(self):
-		return re.sub("TEMPLATETYPE", self.name, user.te_login_user_types)
+    def generate_admin_user_types(self):
+        return re.sub("TEMPLATETYPE", self.name, user.te_admin_user_types)
 
-	def generate_admin_user_types(self):
-		return re.sub("TEMPLATETYPE", self.name, user.te_admin_user_types)
+    def generate_existing_user_types(self):
+        if len(self.existing_domains) == 0:
+            raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type])
+        newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types)
+        newte += """gen_require(`"""
 
-	def generate_existing_user_types(self):
-                if len(self.existing_domains) == 0:
-                    raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type])
-                newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types)
-                newte += """gen_require(`"""
-
-                for d in self.existing_domains:
-                    newte += """
+        for d in self.existing_domains:
+            newte += """
         type %s;""" % d
-                    role = d.split("_t")[0] + "_r"
-                    if role in self.all_roles:
-                        newte += """
-	role %s;""" % role
+            role = d.split("_t")[0] + "_r"
+            if role in self.all_roles:
                 newte += """
+	role %s;""" % role
+        newte += """
 ')
 """
-		return newte;
+        return newte
 
-	def generate_x_login_user_types(self):
-		return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_types)
+    def generate_x_login_user_types(self):
+        return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_types)
 
-	def generate_root_user_types(self):
-		return re.sub("TEMPLATETYPE", self.name, user.te_root_user_types)
+    def generate_root_user_types(self):
+        return re.sub("TEMPLATETYPE", self.name, user.te_root_user_types)
 
-	def generate_new_types(self):
-                newte = ""
-                if len(self.types) == 0:
-                    raise ValueError(_("Type field required"))
-                    
-                for t in self.types:
-                    for i in self.DEFAULT_EXT:
-                        if t.endswith(i):
-                            print t, t[:-len(i)]
-                            newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types)
-                            break
+    def generate_new_types(self):
+        newte = ""
+        if len(self.types) == 0:
+            raise ValueError(_("Type field required"))
 
-                if NEWTYPE and newte == "":
-                    default_ext = []
-                    for i in self.DEFAULT_EXT:
-                        default_ext.append(i)
-                    raise ValueError(_("You need to define a new type which ends with: \n %s") % "\n ".join(default_ext))
+        for t in self.types:
+            for i in self.DEFAULT_EXT:
+                if t.endswith(i):
+                    print t, t[:-len(i)]
+                    newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types)
+                    break
 
-                return newte
+        if NEWTYPE and newte == "":
+            default_ext = []
+            for i in self.DEFAULT_EXT:
+                default_ext.append(i)
+            raise ValueError(_("You need to define a new type which ends with: \n %s") % "\n ".join(default_ext))
 
-	def generate_new_rules(self):
-                return ""
+        return newte
 
-	def generate_daemon_types(self):
-                newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types)
-                if self.initscript != "":
-                    newte += re.sub("TEMPLATETYPE", self.name, executable.te_initscript_types)
-		return newte
+    def generate_new_rules(self):
+        return ""
 
-	def generate_tmp_types(self):
-		if self.use_tmp:
-                    return re.sub("TEMPLATETYPE", self.name, tmp.te_types)
-                else:
-                    return ""
+    def generate_daemon_types(self):
+        newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types)
+        if self.initscript != "":
+            newte += re.sub("TEMPLATETYPE", self.name, executable.te_initscript_types)
+        return newte
 
-	def generate_booleans(self):
-            newte = ""
-            for b in self.booleans:
-                tmp = re.sub("BOOLEAN", b, boolean.te_boolean)
-                newte += re.sub("DESCRIPTION", self.booleans[b], tmp)
-            return newte
+    def generate_tmp_types(self):
+        if self.use_tmp:
+            return re.sub("TEMPLATETYPE", self.name, tmp.te_types)
+        else:
+            return ""
 
-	def generate_boolean_rules(self):
-            newte = ""
-            for b in self.booleans:
-                newte += re.sub("BOOLEAN", b, boolean.te_rules)
-            return newte
+    def generate_booleans(self):
+        newte = ""
+        for b in self.booleans:
+            tmp = re.sub("BOOLEAN", b, boolean.te_boolean)
+            newte += re.sub("DESCRIPTION", self.booleans[b], tmp)
+        return newte
 
-	def generate_sandbox_te(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_types)
+    def generate_boolean_rules(self):
+        newte = ""
+        for b in self.booleans:
+            newte += re.sub("BOOLEAN", b, boolean.te_rules)
+        return newte
 
-	def generate_cgi_te(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_cgi_types)
+    def generate_sandbox_te(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_types)
 
-	def generate_daemon_rules(self):
-                newif =  re.sub("TEMPLATETYPE", self.name, executable.te_daemon_rules)
+    def generate_cgi_te(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_cgi_types)
 
-                return  newif
+    def generate_daemon_rules(self):
+        newif = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_rules)
 
-	def generate_new_type_if(self):
-                newif = ""
-                for t in self.types:
-                    for i in self.DEFAULT_EXT:
-                        if t.endswith(i):
-                            reqtype = t[:-len(i)] + "_t"
-                            newif += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].if_rules)
-                            break
-                return newif
+        return newif
 
-	def generate_login_user_rules(self):
-		return re.sub("TEMPLATETYPE", self.name, user.te_login_user_rules)
+    def generate_new_type_if(self):
+        newif = ""
+        for t in self.types:
+            for i in self.DEFAULT_EXT:
+                if t.endswith(i):
+                    reqtype = t[:-len(i)] + "_t"
+                    newif += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].if_rules)
+                    break
+        return newif
 
-	def generate_existing_user_rules(self):
-		nerules = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_rules)
-                return nerules
+    def generate_login_user_rules(self):
+        return re.sub("TEMPLATETYPE", self.name, user.te_login_user_rules)
 
-	def generate_x_login_user_rules(self):
-		return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_rules)
+    def generate_existing_user_rules(self):
+        nerules = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_rules)
+        return nerules
 
-	def generate_root_user_rules(self):
-                newte =re.sub("TEMPLATETYPE", self.name, user.te_root_user_rules)
-		return newte
+    def generate_x_login_user_rules(self):
+        return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_rules)
 
-	def generate_userapp_rules(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_rules)
+    def generate_root_user_rules(self):
+        newte = re.sub("TEMPLATETYPE", self.name, user.te_root_user_rules)
+        return newte
 
-	def generate_inetd_rules(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_rules)
+    def generate_userapp_rules(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_rules)
 
-	def generate_dbusd_rules(self):
-		return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_rules)
+    def generate_inetd_rules(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_rules)
 
-	def generate_tmp_rules(self):
-		if self.use_tmp:
-                    return re.sub("TEMPLATETYPE", self.name, tmp.te_rules)
-                else:
-                    return ""
+    def generate_dbusd_rules(self):
+        return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_rules)
 
-	def generate_cgi_rules(self):
-		newte = ""
-		newte += re.sub("TEMPLATETYPE", self.name, executable.te_cgi_rules)
-		return newte
+    def generate_tmp_rules(self):
+        if self.use_tmp:
+            return re.sub("TEMPLATETYPE", self.name, tmp.te_rules)
+        else:
+            return ""
 
-	def generate_sandbox_rules(self):
-		newte = ""
-		newte += re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_rules)
-		return newte
+    def generate_cgi_rules(self):
+        newte = ""
+        newte += re.sub("TEMPLATETYPE", self.name, executable.te_cgi_rules)
+        return newte
 
-	def generate_user_if(self):
-                newif =""
-                if self.use_terminal or self.type == USER:
-                    newif = re.sub("TEMPLATETYPE", self.name, executable.if_user_program_rules)
+    def generate_sandbox_rules(self):
+        newte = ""
+        newte += re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_rules)
+        return newte
 
-                if self.type in ( TUSER, XUSER, AUSER, LUSER):
-                    newif += re.sub("TEMPLATETYPE", self.name, executable.if_role_change_rules)
-                return newif
+    def generate_user_if(self):
+        newif = ""
+        if self.use_terminal or self.type == USER:
+            newif = re.sub("TEMPLATETYPE", self.name, executable.if_user_program_rules)
 
-	def generate_if(self):
-                newif = ""
-                newif += re.sub("TEMPLATETYPE", self.name, executable.if_heading_rules)
-                if self.program:
-                    newif += re.sub("TEMPLATETYPE", self.name, executable.if_program_rules)
-                if self.initscript != "":
-                    newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_rules)
+        if self.type in (TUSER, XUSER, AUSER, LUSER):
+            newif += re.sub("TEMPLATETYPE", self.name, executable.if_role_change_rules)
+        return newif
 
-                for d in self.DEFAULT_KEYS:
-			if len(self.DEFAULT_DIRS[d][1]) > 0:
-				newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_rules)
-                                for i in self.DEFAULT_DIRS[d][1]:
-                                        if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
-                                            newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_stream_rules)
-                                            break
-                newif += self.generate_user_if()
-                newif += self.generate_dbus_if()
-                newif += self.generate_admin_if()
-                newif += self.generate_sandbox_if()
-                newif += self.generate_new_type_if()
-                newif += self.generate_new_rules()
+    def generate_if(self):
+        newif = ""
+        newif += re.sub("TEMPLATETYPE", self.name, executable.if_heading_rules)
+        if self.program:
+            newif += re.sub("TEMPLATETYPE", self.name, executable.if_program_rules)
+        if self.initscript != "":
+            newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_rules)
 
-		return newif
+        for d in self.DEFAULT_KEYS:
+            if len(self.DEFAULT_DIRS[d][1]) > 0:
+                newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_rules)
+                for i in self.DEFAULT_DIRS[d][1]:
+                    if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
+                        newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_stream_rules)
+                        break
+        newif += self.generate_user_if()
+        newif += self.generate_dbus_if()
+        newif += self.generate_admin_if()
+        newif += self.generate_sandbox_if()
+        newif += self.generate_new_type_if()
+        newif += self.generate_new_rules()
 
-	def generate_default_types(self):
-		return self.DEFAULT_TYPES[self.type][0]()
+        return newif
 
-	def generate_default_rules(self):
-                if self.DEFAULT_TYPES[self.type][1]:
-                    return self.DEFAULT_TYPES[self.type][1]()
-                return ""
+    def generate_default_types(self):
+        return self.DEFAULT_TYPES[self.type][0]()
 
-	def generate_roles_rules(self):
-            newte = ""
-            if self.type in ( TUSER, XUSER, AUSER, LUSER ):
-                roles = ""
-                if len(self.roles) > 0:
-                    newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules)
-                    newte += re.sub("TEMPLATETYPE", self.name, user.te_newrole_rules)
-                    for role in self.roles:
-                        tmp = re.sub("TEMPLATETYPE", self.name, user.te_roles_rules)
-                        newte += re.sub("ROLE", role, tmp)
-            return newte
+    def generate_default_rules(self):
+        if self.DEFAULT_TYPES[self.type][1]:
+            return self.DEFAULT_TYPES[self.type][1]()
+        return ""
 
-	def generate_te(self):
-		newte = self.generate_default_types()
-                for d in self.DEFAULT_KEYS:
-			if len(self.DEFAULT_DIRS[d][1]) > 0:
-				# CGI scripts already have a rw_t
-				if self.type != CGI or d != "rw":
-                                    newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types)
+    def generate_roles_rules(self):
+        newte = ""
+        if self.type in (TUSER, XUSER, AUSER, LUSER):
+            roles = ""
+            if len(self.roles) > 0:
+                newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules)
+                newte += re.sub("TEMPLATETYPE", self.name, user.te_newrole_rules)
+                for role in self.roles:
+                    tmp = re.sub("TEMPLATETYPE", self.name, user.te_roles_rules)
+                    newte += re.sub("ROLE", role, tmp)
+        return newte
 
-                if self.type != EUSER:
-                    newte +="""
+    def generate_te(self):
+        newte = self.generate_default_types()
+        for d in self.DEFAULT_KEYS:
+            if len(self.DEFAULT_DIRS[d][1]) > 0:
+                # CGI scripts already have a rw_t
+                if self.type != CGI or d != "rw":
+                    newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types)
+
+        if self.type != EUSER:
+            newte += """
 ########################################
 #
 # %s local policy
 #
 """ % self.name
-                newte += self.generate_capabilities()
-                newte += self.generate_process()
-		newte += self.generate_network_types()
-		newte += self.generate_tmp_types()
-		newte += self.generate_booleans()
-		newte += self.generate_default_rules()
-		newte += self.generate_boolean_rules()
+        newte += self.generate_capabilities()
+        newte += self.generate_process()
+        newte += self.generate_network_types()
+        newte += self.generate_tmp_types()
+        newte += self.generate_booleans()
+        newte += self.generate_default_rules()
+        newte += self.generate_boolean_rules()
 
-                for d in self.DEFAULT_KEYS:
-			if len(self.DEFAULT_DIRS[d][1]) > 0:
-                            if self.type == EUSER:
-                                newte_tmp = ""
-                                for domain in self.existing_domains:
-                                    newte_tmp += re.sub("TEMPLATETYPE_t", domain[:-2]+"_t", self.DEFAULT_DIRS[d][2].te_rules)
-                                    newte += re.sub("TEMPLATETYPE_rw_t", self.name+"_rw_t", newte_tmp)
-                            else:
-                                newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules)
-                            for i in self.DEFAULT_DIRS[d][1]:
-                                if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
-                                    if self.type == EUSER:
-                                        for domain in self.existing_domains:
-                                            newte += re.sub("TEMPLATETYPE", domain[:-2], self.DEFAULT_DIRS[d][2].te_stream_rules)
+        for d in self.DEFAULT_KEYS:
+            if len(self.DEFAULT_DIRS[d][1]) > 0:
+                if self.type == EUSER:
+                    newte_tmp = ""
+                    for domain in self.existing_domains:
+                        newte_tmp += re.sub("TEMPLATETYPE_t", domain[:-2] + "_t", self.DEFAULT_DIRS[d][2].te_rules)
+                        newte += re.sub("TEMPLATETYPE_rw_t", self.name + "_rw_t", newte_tmp)
+                else:
+                    newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules)
+                for i in self.DEFAULT_DIRS[d][1]:
+                    if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
+                        if self.type == EUSER:
+                            for domain in self.existing_domains:
+                                newte += re.sub("TEMPLATETYPE", domain[:-2], self.DEFAULT_DIRS[d][2].te_stream_rules)
 
-                                    else:
-                                        newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules)
-                                    break
-
-		newte += self.generate_tmp_rules()
-		newte += self.generate_network_rules()
-		newte += self.generate_fd_rules()
-		newte += self.generate_etc_rules()
-		newte += self.generate_pam_rules()
-		newte += self.generate_uid_rules()
-		newte += self.generate_audit_rules()
-		newte += self.generate_syslog_rules()
-		newte += self.generate_localization_rules()
-		newte += self.generate_resolve_rules()
-		newte += self.generate_roles_rules()
-		newte += self.generate_mail_rules()
-		newte += self.generate_transition_rules()
-		newte += self.generate_admin_rules()
-		newte += self.generate_dbus_rules()
-		newte += self.generate_kerberos_rules()
-		newte += self.generate_manage_krb5_rcache_rules()
-
-		return newte
-
-	def generate_fc(self):
-		newfc = ""
-                fclist = []
-		for i in self.files.keys():
-                        if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
-                            t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_sock_file)
                         else:
-                            t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_file)
-			t2 = re.sub("FILENAME", i, t1)
-                        fclist.append(re.sub("FILETYPE", self.files[i][0], t2))
+                            newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules)
+                        break
 
-		for i in self.dirs.keys():
-			t1 = re.sub("TEMPLATETYPE", self.name, self.dirs[i][2].fc_dir)
-			t2 = re.sub("FILENAME", i, t1)
-                        fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2))
+        newte += self.generate_tmp_rules()
+        newte += self.generate_network_rules()
+        newte += self.generate_fd_rules()
+        newte += self.generate_etc_rules()
+        newte += self.generate_pam_rules()
+        newte += self.generate_uid_rules()
+        newte += self.generate_audit_rules()
+        newte += self.generate_syslog_rules()
+        newte += self.generate_localization_rules()
+        newte += self.generate_resolve_rules()
+        newte += self.generate_roles_rules()
+        newte += self.generate_mail_rules()
+        newte += self.generate_transition_rules()
+        newte += self.generate_admin_rules()
+        newte += self.generate_dbus_rules()
+        newte += self.generate_kerberos_rules()
+        newte += self.generate_manage_krb5_rcache_rules()
 
-                if self.type in USERS +  [ SANDBOX ]:
-                    if len(fclist) == 0:
-                        return executable.fc_user
+        return newte
 
-                if self.type not in USERS + [ SANDBOX, EUSER,  NEWTYPE ] and not self.program:
-                    raise ValueError(_("You must enter the executable path for your confined process"))
-
-                if self.program:
-                    t1 = re.sub("EXECUTABLE", self.program, executable.fc_program)
-                    fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
-
-                if self.initscript != "":
-                    t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript)
-                    fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
-
-                fclist.sort()
-                newfc="\n".join(fclist)
-		return newfc
-
-	def generate_user_sh(self):
-            newsh = ""
-            if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER):
-                return newsh
-
-            roles = ""
-            for role in self.roles:
-                roles += " %s_r" % role
-            if roles != "":
-                roles += " system_r"
-            tmp = re.sub("TEMPLATETYPE", self.name, script.users)
-            newsh += re.sub("ROLES", roles, tmp)
-
-            if self.type == RUSER or self.type == AUSER:
-                for u in self.transition_users:
-                    tmp =  re.sub("TEMPLATETYPE", self.name, script.admin_trans)
-                    newsh += re.sub("USER", u, tmp)
-
-            if self.type == LUSER:
-                    newsh +=  re.sub("TEMPLATETYPE", self.name, script.min_login_user_default_context)
+    def generate_fc(self):
+        newfc = ""
+        fclist = []
+        for i in self.files.keys():
+            if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
+                t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_sock_file)
             else:
-                    newsh +=  re.sub("TEMPLATETYPE", self.name, script.x_login_user_default_context)
+                t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_file)
+            t2 = re.sub("FILENAME", i, t1)
+            fclist.append(re.sub("FILETYPE", self.files[i][0], t2))
 
+        for i in self.dirs.keys():
+            t1 = re.sub("TEMPLATETYPE", self.name, self.dirs[i][2].fc_dir)
+            t2 = re.sub("FILENAME", i, t1)
+            fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2))
 
+        if self.type in USERS + [SANDBOX]:
+            if len(fclist) == 0:
+                return executable.fc_user
+
+        if self.type not in USERS + [SANDBOX, EUSER, NEWTYPE] and not self.program:
+            raise ValueError(_("You must enter the executable path for your confined process"))
+
+        if self.program:
+            t1 = re.sub("EXECUTABLE", self.program, executable.fc_program)
+            fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
+
+        if self.initscript != "":
+            t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript)
+            fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
+
+        fclist.sort()
+        newfc = "\n".join(fclist)
+        return newfc
+
+    def generate_user_sh(self):
+        newsh = ""
+        if self.type not in (TUSER, XUSER, AUSER, LUSER, RUSER):
             return newsh
 
-	def generate_sh(self):
-                temp  = re.sub("TEMPLATETYPE", self.file_name, script.compile)
-                temp  = re.sub("DOMAINTYPE", self.name, temp)
-                if self.type == EUSER:
-                    newsh  = re.sub("TEMPLATEFILE", "%s" % self.file_name, temp)
-                else:
-                    newsh  = re.sub("TEMPLATEFILE", self.file_name, temp)
-                    newsh += re.sub("DOMAINTYPE", self.name, script.manpage)
+        roles = ""
+        for role in self.roles:
+            roles += " %s_r" % role
+        if roles != "":
+            roles += " system_r"
+        tmp = re.sub("TEMPLATETYPE", self.name, script.users)
+        newsh += re.sub("ROLES", roles, tmp)
 
-                if self.program:
-                    newsh += re.sub("FILENAME", self.program, script.restorecon)
-                if self.initscript != "":
-                    newsh += re.sub("FILENAME", self.initscript, script.restorecon)
+        if self.type == RUSER or self.type == AUSER:
+            for u in self.transition_users:
+                tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans)
+                newsh += re.sub("USER", u, tmp)
 
-		for i in self.files.keys():
-			newsh += re.sub("FILENAME", i, script.restorecon)
+        if self.type == LUSER:
+            newsh += re.sub("TEMPLATETYPE", self.name, script.min_login_user_default_context)
+        else:
+            newsh += re.sub("TEMPLATETYPE", self.name, script.x_login_user_default_context)
 
-		for i in self.dirs.keys():
-			newsh += re.sub("FILENAME", i, script.restorecon)
+        return newsh
 
-                for i in self.in_tcp[PORTS] + self.out_tcp[PORTS]:
-                    if self.find_port(i,"tcp") == None:
-                        t1 = re.sub("PORTNUM", "%d" % i, script.tcp_ports)
-                        newsh += re.sub("TEMPLATETYPE", self.name, t1)
+    def generate_sh(self):
+        temp = re.sub("TEMPLATETYPE", self.file_name, script.compile)
+        temp = re.sub("DOMAINTYPE", self.name, temp)
+        if self.type == EUSER:
+            newsh = re.sub("TEMPLATEFILE", "%s" % self.file_name, temp)
+        else:
+            newsh = re.sub("TEMPLATEFILE", self.file_name, temp)
+            newsh += re.sub("DOMAINTYPE", self.name, script.manpage)
 
-                for i in self.in_udp[PORTS]:
-                    if self.find_port(i,"udp") == None:
-			t1 = re.sub("PORTNUM", "%d" % i, script.udp_ports)
-			newsh += re.sub("TEMPLATETYPE", self.name, t1)
+        if self.program:
+            newsh += re.sub("FILENAME", self.program, script.restorecon)
+        if self.initscript != "":
+            newsh += re.sub("FILENAME", self.initscript, script.restorecon)
 
-                newsh += self.generate_user_sh()
-                if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat","centos","SuSE","fedora","mandrake","mandriva")):
-                    newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm)
+        for i in self.files.keys():
+            newsh += re.sub("FILENAME", i, script.restorecon)
 
-		return newsh
+        for i in self.dirs.keys():
+            newsh += re.sub("FILENAME", i, script.restorecon)
 
-	def generate_spec(self):
-	 	newspec = ""
+        for i in self.in_tcp[PORTS] + self.out_tcp[PORTS]:
+            if self.find_port(i, "tcp") == None:
+                t1 = re.sub("PORTNUM", "%d" % i, script.tcp_ports)
+                newsh += re.sub("TEMPLATETYPE", self.name, t1)
 
-		selinux_policyver = get_rpm_nvr_list("selinux-policy")[1]
-		POLICYCOREUTILSVER = get_rpm_nvr_list("checkpolicy")[1]
+        for i in self.in_udp[PORTS]:
+            if self.find_port(i, "udp") == None:
+                t1 = re.sub("PORTNUM", "%d" % i, script.udp_ports)
+                newsh += re.sub("TEMPLATETYPE", self.name, t1)
 
-                newspec += spec.header_comment_section
-		if self.type in APPLICATIONS:
-			newspec += spec.define_relabel_files_begin
-			if self.program:
-				newspec += re.sub("FILENAME", self.program, spec.define_relabel_files_end)
-			if self.initscript != "":
-				newspec += re.sub("FILENAME", self.initscript, spec.define_relabel_files_end)
-			for i in self.files.keys():
-				newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
-			for i in self.dirs.keys():
-				newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
+        newsh += self.generate_user_sh()
+        if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat", "centos", "SuSE", "fedora", "mandrake", "mandriva")):
+            newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm)
 
-                newspec += re.sub("VERSION", selinux_policyver, spec.base_section)
-                newspec = re.sub("MODULENAME", self.file_name, newspec)
-                newspec = re.sub("DOMAINNAME", self.name, newspec)
-                if len(self.rpms) > 0:
-                    newspec += "Requires(post): %s\n" % ", ".join(self.rpms)
-                newspec += re.sub("MODULENAME", self.file_name, spec.mid_section)
-                newspec = re.sub("DOMAINNAME", self.name, newspec)
-                newspec = re.sub("TODAYSDATE", time.strftime("%a %b %e %Y"), newspec) 
+        return newsh
 
-		if self.type not in APPLICATIONS:
-                    newspec = re.sub("%relabel_files", "", newspec) 
-                    
-                # Remove man pages from EUSER spec file
-                if self.type == EUSER:
-                    newspec = re.sub(".*%s_selinux.8.*" % self.name,"", newspec)
-                # Remove user context file from non users spec file
-                if self.type not in ( TUSER, XUSER, AUSER, LUSER, RUSER):
-                    newspec = re.sub(".*%s_u.*" % self.name,"", newspec)
-                return newspec
+    def generate_spec(self):
+        newspec = ""
 
-	def write_spec(self, out_dir):
-		specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name)
-		fd = open(specfile, "w")
-		fd.write(self.generate_spec())
-		fd.close()
+        selinux_policyver = get_rpm_nvr_list("selinux-policy")[1]
+        POLICYCOREUTILSVER = get_rpm_nvr_list("checkpolicy")[1]
 
-		return specfile
+        newspec += spec.header_comment_section
+        if self.type in APPLICATIONS:
+            newspec += spec.define_relabel_files_begin
+            if self.program:
+                newspec += re.sub("FILENAME", self.program, spec.define_relabel_files_end)
+            if self.initscript != "":
+                newspec += re.sub("FILENAME", self.initscript, spec.define_relabel_files_end)
+            for i in self.files.keys():
+                newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
+            for i in self.dirs.keys():
+                newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
 
-	def write_te(self, out_dir):
-                tefile = "%s/%s.te" % (out_dir, self.file_name)
-		fd = open(tefile, "w")
-		fd.write(self.generate_te())
-		fd.close()
-		return tefile
+        newspec += re.sub("VERSION", selinux_policyver, spec.base_section)
+        newspec = re.sub("MODULENAME", self.file_name, newspec)
+        newspec = re.sub("DOMAINNAME", self.name, newspec)
+        if len(self.rpms) > 0:
+            newspec += "Requires(post): %s\n" % ", ".join(self.rpms)
+        newspec += re.sub("MODULENAME", self.file_name, spec.mid_section)
+        newspec = re.sub("DOMAINNAME", self.name, newspec)
+        newspec = re.sub("TODAYSDATE", time.strftime("%a %b %e %Y"), newspec)
 
-	def write_sh(self, out_dir):
-                shfile = "%s/%s.sh" % (out_dir, self.file_name)
-		fd = open(shfile, "w")
-		fd.write(self.generate_sh())
-		fd.close()
-                os.chmod(shfile, 0750)
-		return shfile
+        if self.type not in APPLICATIONS:
+            newspec = re.sub("%relabel_files", "", newspec)
 
-	def write_if(self, out_dir):
-                iffile = "%s/%s.if" % (out_dir, self.file_name)
-		fd = open(iffile, "w")
-		fd.write(self.generate_if())
-		fd.close()
-		return iffile
+        # Remove man pages from EUSER spec file
+        if self.type == EUSER:
+            newspec = re.sub(".*%s_selinux.8.*" % self.name, "", newspec)
+        # Remove user context file from non users spec file
+        if self.type not in (TUSER, XUSER, AUSER, LUSER, RUSER):
+            newspec = re.sub(".*%s_u.*" % self.name, "", newspec)
+        return newspec
 
-	def write_fc(self,out_dir):
-                fcfile = "%s/%s.fc" % (out_dir, self.file_name)
-                fd = open(fcfile, "w")
-                fd.write(self.generate_fc())
-                fd.close()
-		return fcfile
+    def write_spec(self, out_dir):
+        specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name)
+        fd = open(specfile, "w")
+        fd.write(self.generate_spec())
+        fd.close()
 
-        def __extract_rpms(self):
-            import yum
-            yb = yum.YumBase()
-            yb.setCacheDir()
+        return specfile
 
-            for pkg in yb.rpmdb.searchProvides(self.program):
-                self.rpms.append(pkg.name)
-                for fname in pkg.dirlist + pkg.filelist + pkg.ghostlist:
+    def write_te(self, out_dir):
+        tefile = "%s/%s.te" % (out_dir, self.file_name)
+        fd = open(tefile, "w")
+        fd.write(self.generate_te())
+        fd.close()
+        return tefile
+
+    def write_sh(self, out_dir):
+        shfile = "%s/%s.sh" % (out_dir, self.file_name)
+        fd = open(shfile, "w")
+        fd.write(self.generate_sh())
+        fd.close()
+        os.chmod(shfile, 0750)
+        return shfile
+
+    def write_if(self, out_dir):
+        iffile = "%s/%s.if" % (out_dir, self.file_name)
+        fd = open(iffile, "w")
+        fd.write(self.generate_if())
+        fd.close()
+        return iffile
+
+    def write_fc(self, out_dir):
+        fcfile = "%s/%s.fc" % (out_dir, self.file_name)
+        fd = open(fcfile, "w")
+        fd.write(self.generate_fc())
+        fd.close()
+        return fcfile
+
+    def __extract_rpms(self):
+        import yum
+        yb = yum.YumBase()
+        yb.setCacheDir()
+
+        for pkg in yb.rpmdb.searchProvides(self.program):
+            self.rpms.append(pkg.name)
+            for fname in pkg.dirlist + pkg.filelist + pkg.ghostlist:
+                for b in self.DEFAULT_DIRS:
+                    if b == "/etc":
+                        continue
+                    if fname.startswith(b):
+                        if os.path.isfile(fname):
+                            self.add_file(fname)
+                        else:
+                            self.add_dir(fname)
+
+            for bpkg in yb.rpmdb.searchNames([pkg.base_package_name]):
+                for fname in bpkg.dirlist + bpkg.filelist + bpkg.ghostlist:
                     for b in self.DEFAULT_DIRS:
                         if b == "/etc":
                             continue
@@ -1269,107 +1284,96 @@
                             else:
                                 self.add_dir(fname)
 
-                for bpkg in yb.rpmdb.searchNames([pkg.base_package_name]):
-                    for fname in bpkg.dirlist + bpkg.filelist + bpkg.ghostlist:
-                        for b in self.DEFAULT_DIRS:
-                            if b == "/etc":
-                                continue
-                            if fname.startswith(b):
-                                if os.path.isfile(fname):
-                                    self.add_file(fname)
-                                else:
-                                    self.add_dir(fname)
+        # some packages have own systemd subpackage
+        # tor-systemd for example
+        binary_name = self.program.split("/")[-1]
+        for bpkg in yb.rpmdb.searchNames(["%s-systemd" % binary_name]):
+            for fname in bpkg.filelist + bpkg.ghostlist + bpkg.dirlist:
+                for b in self.DEFAULT_DIRS:
+                    if b == "/etc":
+                        continue
+                    if fname.startswith(b):
+                        if os.path.isfile(fname):
+                            self.add_file(fname)
+                        else:
+                            self.add_dir(fname)
 
-            # some packages have own systemd subpackage
-            # tor-systemd for example
-            binary_name = self.program.split("/")[-1]
-            for bpkg in yb.rpmdb.searchNames([ "%s-systemd" % binary_name ]):
-                for fname in bpkg.filelist + bpkg.ghostlist + bpkg.dirlist:
-                    for b in self.DEFAULT_DIRS:
-                        if b == "/etc":
-                            continue
-                        if fname.startswith(b):
-                            if os.path.isfile(fname):
-                                self.add_file(fname)
-                            else:
-                                self.add_dir(fname)
+    def gen_writeable(self):
+        try:
+            self.__extract_rpms()
+        except ImportError:
+            pass
 
-        def gen_writeable(self):
+        if os.path.isfile("/var/run/%s.pid" % self.name):
+            self.add_file("/var/run/%s.pid" % self.name)
+
+        if os.path.isdir("/var/run/%s" % self.name):
+            self.add_dir("/var/run/%s" % self.name)
+
+        if os.path.isdir("/var/log/%s" % self.name):
+            self.add_dir("/var/log/%s" % self.name)
+
+        if os.path.isfile("/var/log/%s.log" % self.name):
+            self.add_file("/var/log/%s.log" % self.name)
+
+        if os.path.isdir("/var/lib/%s" % self.name):
+            self.add_dir("/var/lib/%s" % self.name)
+
+        if os.path.isfile("/etc/rc.d/init.d/%s" % self.name):
+            self.set_init_script("/etc/rc\.d/init\.d/%s" % self.name)
+
+        # we don't want to have subdir in the .fc policy file
+        # if we already specify labeling for parent dir
+        temp_basepath = []
+        for p in self.DEFAULT_DIRS.keys():
+            temp_dirs = []
             try:
-                self.__extract_rpms()
-            except ImportError:
-                pass
+                temp_basepath = self.DEFAULT_DIRS[p][1][0] + "/"
+            except IndexError:
+                continue
 
-            if os.path.isfile("/var/run/%s.pid"  % self.name):
-                self.add_file("/var/run/%s.pid"  % self.name)
-
-            if os.path.isdir("/var/run/%s"  % self.name):
-                self.add_dir("/var/run/%s"  % self.name)
-
-            if os.path.isdir("/var/log/%s"  % self.name):
-                self.add_dir("/var/log/%s"  % self.name)
-
-            if os.path.isfile("/var/log/%s.log"  % self.name):
-                self.add_file("/var/log/%s.log"  % self.name)
-
-            if os.path.isdir("/var/lib/%s"  % self.name):
-                self.add_dir("/var/lib/%s"  % self.name)
-
-            if os.path.isfile("/etc/rc.d/init.d/%s"  % self.name):
-                self.set_init_script("/etc/rc\.d/init\.d/%s"  % self.name)
-
-            # we don't want to have subdir in the .fc policy file 
-            # if we already specify labeling for parent dir
-            temp_basepath = []
-            for p in self.DEFAULT_DIRS.keys():
-                temp_dirs = []
-                try:
-                    temp_basepath = self.DEFAULT_DIRS[p][1][0] + "/"
-                except IndexError:
+            for i in self.DEFAULT_DIRS[p][1]:
+                if i.startswith(temp_basepath):
+                    temp_dirs.append(i)
+                else:
                     continue
 
-                for i in self.DEFAULT_DIRS[p][1]:
-                    if i.startswith(temp_basepath):
-                        temp_dirs.append(i)
+            if len(temp_dirs) is not 0:
+                for i in temp_dirs:
+                    if i in self.dirs.keys():
+                        del(self.dirs[i])
+                    elif i in self.files.keys():
+                        del(self.files[i])
                     else:
                         continue
 
-                if len(temp_dirs) is not 0:
-                    for i in temp_dirs:
-                        if i in self.dirs.keys():
-                            del(self.dirs[i])
-                        elif i in self.files.keys():
-                            del(self.files[i])
-                        else:
-                            continue
+                self.DEFAULT_DIRS[p][1] = list(set(self.DEFAULT_DIRS[p][1]) - set(temp_dirs))
 
-                    self.DEFAULT_DIRS[p][1] = list(set(self.DEFAULT_DIRS[p][1]) - set(temp_dirs))
-
-        def gen_symbols(self):
-            if self.type not in APPLICATIONS:
-                return
-            if not os.path.exists(self.program):
-                sys.stderr.write("""
+    def gen_symbols(self):
+        if self.type not in APPLICATIONS:
+            return
+        if not os.path.exists(self.program):
+            sys.stderr.write("""
 ***************************************
 Warning %s does not exist
 ***************************************
 
 """ % self.program)
-                return
-            fd = os.popen("nm -D %s | grep U" % self.program)
-            for s in fd.read().split():
-                for b in self.symbols:
-                    if s.startswith(b):
-                        exec "self.%s" %  self.symbols[b]
-            fd.close()
+            return
+        fd = os.popen("nm -D %s | grep U" % self.program)
+        for s in fd.read().split():
+            for b in self.symbols:
+                if s.startswith(b):
+                    exec "self.%s" % self.symbols[b]
+        fd.close()
 
-	def generate(self, out_dir = os.getcwd() ):
-            out = "Created the following files:\n"
-            out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file"))
-            out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file"))
-            out += "%s # %s\n" % (self.write_fc(out_dir), _("File Contexts file"))
-            if self.type != NEWTYPE:
-                if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat","centos","SuSE","fedora","mandrake","mandriva")):
-                    out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file"))
-                out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script"))
-            return out
+    def generate(self, out_dir=os.getcwd()):
+        out = "Created the following files:\n"
+        out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file"))
+        out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file"))
+        out += "%s # %s\n" % (self.write_fc(out_dir), _("File Contexts file"))
+        if self.type != NEWTYPE:
+            if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat", "centos", "SuSE", "fedora", "mandrake", "mandriva")):
+                out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file"))
+            out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script"))
+        return out
diff --git a/policycoreutils/sepolicy/sepolicy/gui.py b/policycoreutils/sepolicy/sepolicy/gui.py
index 5ca87b9..313b77f 100644
--- a/policycoreutils/sepolicy/sepolicy/gui.py
+++ b/policycoreutils/sepolicy/sepolicy/gui.py
@@ -38,18 +38,19 @@
 import sepolicy.manpage
 import dbus
 import time
-import os, re
+import os
+import re
 import gettext
 import unicodedata
 
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
 gettext.textdomain(PROGNAME)
 try:
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
@@ -58,37 +59,39 @@
 for f in sepolicy.file_type_str:
     reverse_file_type_str[sepolicy.file_type_str[f]] = f
 
-enabled=[_("No"), _("Yes")]
-action=[_("Disable"), _("Enable")]
+enabled = [_("No"), _("Yes")]
+action = [_("Disable"), _("Enable")]
+
+
 def compare(a, b):
-    return cmp(a.lower(),b.lower())
+    return cmp(a.lower(), b.lower())
 
 import distutils.sysconfig
-ADVANCED_LABEL = ( _("Advanced >>"), _("Advanced <<") )
-ADVANCED_SEARCH_LABEL = ( _("Advanced Search >>"), _("Advanced Search <<") )
+ADVANCED_LABEL = (_("Advanced >>"), _("Advanced <<"))
+ADVANCED_SEARCH_LABEL = (_("Advanced Search >>"), _("Advanced Search <<"))
 OUTBOUND_PAGE = 0
 INBOUND_PAGE = 1
 
-TRANSITIONS_FROM_PAGE=0
-TRANSITIONS_TO_PAGE=1
-TRANSITIONS_FILE_PAGE=2
+TRANSITIONS_FROM_PAGE = 0
+TRANSITIONS_TO_PAGE = 1
+TRANSITIONS_FILE_PAGE = 2
 
 EXE_PAGE = 0
 WRITABLE_PAGE = 1
 APP_PAGE = 2
 
-BOOLEANS_PAGE=0
-FILES_PAGE=1
-NETWORK_PAGE=2
-TRANSITIONS_PAGE=3
-LOGIN_PAGE=4
-USER_PAGE=5
-LOCKDOWN_PAGE=6
-SYSTEM_PAGE=7
-FILE_EQUIV_PAGE=8
-START_PAGE=9
+BOOLEANS_PAGE = 0
+FILES_PAGE = 1
+NETWORK_PAGE = 2
+TRANSITIONS_PAGE = 3
+LOGIN_PAGE = 4
+USER_PAGE = 5
+LOCKDOWN_PAGE = 6
+SYSTEM_PAGE = 7
+FILE_EQUIV_PAGE = 8
+START_PAGE = 9
 
-keys = ["boolean", "fcontext", "fcontext-equiv", "port", "login", "user", "module", "node", "interface" ]
+keys = ["boolean", "fcontext", "fcontext-equiv", "port", "login", "user", "module", "node", "interface"]
 
 DISABLED_TEXT = _("""<small>
 To change from Disabled to Enforcing mode
@@ -98,9 +101,10 @@
   * Change the system mode to Enforcing</small>
 """)
 
+
 class SELinuxGui():
 
-    def __init__( self , app = None, test = False):
+    def __init__(self, app=None, test=False):
         self.finish_init = False
         self.opage = START_PAGE
         self.dbus = SELinuxDBus()
@@ -119,8 +123,8 @@
         self.init_cur()
         self.application = app
         self.filter_txt = ""
-        builder = Gtk.Builder() # BUILDER OBJ
-        self.code_path = distutils.sysconfig.get_python_lib(plat_specific = True) + "/sepolicy/"
+        builder = Gtk.Builder()  # BUILDER OBJ
+        self.code_path = distutils.sysconfig.get_python_lib(plat_specific=True) + "/sepolicy/"
         glade_file = self.code_path + "sepolicy.glade"
         builder.add_from_file(glade_file)
         self.outer_notebook = builder.get_object("outer_notebook")
@@ -314,7 +318,7 @@
         self.files_delete_liststore = builder.get_object("files_delete_liststore")
         self.network_delete_window = builder.get_object("network_delete_window")
         self.network_delete_treeview = builder.get_object("network_delete_treeview")
-        self.network_delete_liststore =builder.get_object("network_delete_liststore")
+        self.network_delete_liststore = builder.get_object("network_delete_liststore")
         # Delete items **************************************
 
         # Progress bar **************************************
@@ -323,7 +327,7 @@
 
         # executable_files items ****************************
         self.executable_files_treeview = builder.get_object("Executable_files_treeview")                  # Get the executable files tree view
-        self.executable_files_filter= builder.get_object("executable_files_filter")
+        self.executable_files_filter = builder.get_object("executable_files_filter")
         self.executable_files_filter.set_visible_func(self.filter_the_data)
         self.executable_files_tab = builder.get_object("Executable_files_tab")
         self.executable_files_tab_tooltip_txt = self.executable_files_tab.get_tooltip_text()
@@ -363,7 +367,7 @@
         self.network_out_treeview = builder.get_object("outbound_treeview")
         self.network_out_liststore = builder.get_object("network_out_liststore")
         self.network_out_liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)
-        self.network_out_filter =  builder.get_object("network_out_filter")
+        self.network_out_filter = builder.get_object("network_out_filter")
         self.network_out_filter.set_visible_func(self.filter_the_data)
         self.network_out_tab = builder.get_object("network_out_tab")
         self.network_out_tab_tooltip_txt = self.network_out_tab.get_tooltip_text()
@@ -371,7 +375,7 @@
         self.network_in_treeview = builder.get_object("inbound_treeview")
         self.network_in_liststore = builder.get_object("network_in_liststore")
         self.network_in_liststore.set_sort_column_id(0, Gtk.SortType.ASCENDING)
-        self.network_in_filter =  builder.get_object("network_in_filter")
+        self.network_in_filter = builder.get_object("network_in_filter")
         self.network_in_filter.set_visible_func(self.filter_the_data)
         self.network_in_tab = builder.get_object("network_in_tab")
         self.network_in_tab_tooltip_txt = self.network_in_tab.get_tooltip_text()
@@ -424,7 +428,7 @@
         # Combobox and Entry items **************************
         self.combobox_menu = builder.get_object("combobox_org")                    # This is the combobox box object, aka the arrow next to the entry text bar
         self.combobox_menu_model = builder.get_object("application_liststore")
-        self.completion_entry = builder.get_object("completion_entry")        #self.combobox_menu.get_child()
+        self.completion_entry = builder.get_object("completion_entry")  # self.combobox_menu.get_child()
         self.completion_entry_model = builder.get_object("application_liststore")
         self.entrycompletion_obj = builder.get_object("entrycompletion_obj")
         #self.entrycompletion_obj = Gtk.EntryCompletion()
@@ -483,7 +487,7 @@
         self.loading = 1
         path = None
         if test:
-            domains = [ "httpd_t", "abrt_t" ]
+            domains = ["httpd_t", "abrt_t"]
             if app and app not in domains:
                 domains.append(app)
         else:
@@ -497,7 +501,7 @@
             self.combo_box_initialize(domain, None)
             self.advanced_search_initialize(domain)
             self.all_list.append(domain)
-            self.percentage = float(float(self.loading)/float(length))
+            self.percentage = float(float(self.loading) / float(length))
             self.progress_bar.set_fraction(self.percentage)
             self.progress_bar.set_pulse_step(self.percentage)
             self.idle_func()
@@ -516,84 +520,84 @@
         loading_gui.hide()
 
         dic = {
-               "on_combo_button_clicked" : self.open_combo_menu,
-               "on_disable_ptrace_toggled" : self.on_disable_ptrace,
-               "on_SELinux_window_configure_event" : self.hide_combo_menu,
-               "on_entrycompletion_obj_match_selected" : self.set_application_label,
-               "on_filter_changed" : self.get_filter_data,
-               "on_save_changes_file_equiv_clicked" : self.update_to_file_equiv,
-               "on_save_changes_login_clicked" : self.update_to_login,
-               "on_save_changes_user_clicked" : self.update_to_user,
-               "on_save_changes_files_clicked" : self.update_to_files,
-               "on_save_changes_network_clicked" : self.update_to_network,
-               "on_Advanced_text_files_button_press_event" : self.reveal_advanced,
-               "item_in_tree_selected" : self.cursor_changed,
-               "on_Application_file_types_treeview_configure_event" : self.resize_wrap,
-               "on_save_delete_clicked" : self.on_save_delete_clicked,
-               "on_moreTypes_treeview_files_row_activated" : self.populate_type_combo,
-               "on_retry_button_files_clicked" : self.invalid_entry_retry,
-               "on_make_path_recursive_toggled" : self.recursive_path,
-               "on_files_path_entry_button_press_event" : self.highlight_entry_text,
-               "on_files_path_entry_changed" : self.autofill_add_files_entry,
-               "on_select_type_files_clicked" : self.select_type_more,
-               "on_choose_file" : self.on_browse_select,
-               "on_Enforcing_button_toggled" : self.set_enforce,
-               "on_confirmation_close" : self.confirmation_close,
-               "on_column_clicked" : self.column_clicked,
-               "on_tab_switch" : self.clear_filters,
+            "on_combo_button_clicked": self.open_combo_menu,
+            "on_disable_ptrace_toggled": self.on_disable_ptrace,
+            "on_SELinux_window_configure_event": self.hide_combo_menu,
+            "on_entrycompletion_obj_match_selected": self.set_application_label,
+            "on_filter_changed": self.get_filter_data,
+            "on_save_changes_file_equiv_clicked": self.update_to_file_equiv,
+            "on_save_changes_login_clicked": self.update_to_login,
+            "on_save_changes_user_clicked": self.update_to_user,
+            "on_save_changes_files_clicked": self.update_to_files,
+            "on_save_changes_network_clicked": self.update_to_network,
+            "on_Advanced_text_files_button_press_event": self.reveal_advanced,
+            "item_in_tree_selected": self.cursor_changed,
+            "on_Application_file_types_treeview_configure_event": self.resize_wrap,
+            "on_save_delete_clicked": self.on_save_delete_clicked,
+            "on_moreTypes_treeview_files_row_activated": self.populate_type_combo,
+            "on_retry_button_files_clicked": self.invalid_entry_retry,
+            "on_make_path_recursive_toggled": self.recursive_path,
+            "on_files_path_entry_button_press_event": self.highlight_entry_text,
+            "on_files_path_entry_changed": self.autofill_add_files_entry,
+            "on_select_type_files_clicked": self.select_type_more,
+            "on_choose_file": self.on_browse_select,
+            "on_Enforcing_button_toggled": self.set_enforce,
+            "on_confirmation_close": self.confirmation_close,
+            "on_column_clicked": self.column_clicked,
+            "on_tab_switch": self.clear_filters,
 
-               "on_file_equiv_button_clicked" : self.show_file_equiv_page,
-               "on_app/system_button_clicked" : self.system_interface,
-               "on_app/users_button_clicked" : self.users_interface,
-               "on_main_advanced_label_button_press_event": self.advanced_label_main,
+            "on_file_equiv_button_clicked": self.show_file_equiv_page,
+            "on_app/system_button_clicked": self.system_interface,
+            "on_app/users_button_clicked": self.users_interface,
+            "on_main_advanced_label_button_press_event": self.advanced_label_main,
 
-               "on_Show_mislabeled_files_toggled" : self.show_mislabeled_files,
-               "on_Browse_button_files_clicked" : self.browse_for_files,
-               "on_cancel_popup_clicked" : self.close_popup,
-               "on_treeview_cursor_changed" : self.cursor_changed,
-               "on_login_seuser_combobox_changed"  : self.login_seuser_combobox_change,
-               "on_user_roles_combobox_changed":self.user_roles_combobox_change,
+            "on_Show_mislabeled_files_toggled": self.show_mislabeled_files,
+            "on_Browse_button_files_clicked": self.browse_for_files,
+            "on_cancel_popup_clicked": self.close_popup,
+            "on_treeview_cursor_changed": self.cursor_changed,
+            "on_login_seuser_combobox_changed": self.login_seuser_combobox_change,
+            "on_user_roles_combobox_changed": self.user_roles_combobox_change,
 
-               "on_cancel_button_browse_clicked" : self.close_config_window,
-               "on_apply_button_clicked" : self.apply_changes_button_press,
-               "on_Revert_button_clicked" : self.update_or_revert_changes,
-               "on_Update_button_clicked" : self.update_or_revert_changes,
-               "on_advanced_filter_entry_changed" : self.get_advanced_filter_data,
-               "on_advanced_search_treeview_row_activated" : self.advanced_item_selected,
-               "on_Select_advanced_search_clicked" : self.advanced_item_button_push,
-               "on_All_advanced_button_toggled" : self.advanced_radio_select,
-               "on_Installed_advanced_button_toggled" : self.advanced_radio_select,
-               "on_info_button_button_press_event" : self.on_help_button,
-               "on_back_button_clicked" : self.on_help_back_clicked,
-               "on_forward_button_clicked" : self.on_help_forward_clicked,
-               "on_Boolean_treeview_columns_changed" : self.resize_columns,
-               "on_completion_entry_changed" : self.application_selected,
-               "on_Add_button_clicked" : self.add_button_clicked,
-               "on_Delete_button_clicked" : self.delete_button_clicked,
-               "on_Modify_button_clicked" : self.modify_button_clicked,
-               "on_Show_modified_only_toggled" : self.on_show_modified_only,
-               "on_cancel_button_config_clicked" : self.close_config_window,
-               "on_Import_button_clicked" : self.import_config_show,
-               "on_Export_button_clicked" : self.export_config_show,
-               "on_enable_unconfined_toggled": self.unconfined_toggle,
-               "on_enable_permissive_toggled": self.permissive_toggle,
-               "on_system_policy_type_combobox_changed" : self.change_default_policy,
-               "on_Enforcing_button_default_toggled" : self.change_default_mode,
-               "on_Permissive_button_default_toggled" : self.change_default_mode,
-               "on_Disabled_button_default_toggled" : self.change_default_mode,
+            "on_cancel_button_browse_clicked": self.close_config_window,
+            "on_apply_button_clicked": self.apply_changes_button_press,
+            "on_Revert_button_clicked": self.update_or_revert_changes,
+            "on_Update_button_clicked": self.update_or_revert_changes,
+            "on_advanced_filter_entry_changed": self.get_advanced_filter_data,
+            "on_advanced_search_treeview_row_activated": self.advanced_item_selected,
+            "on_Select_advanced_search_clicked": self.advanced_item_button_push,
+            "on_All_advanced_button_toggled": self.advanced_radio_select,
+            "on_Installed_advanced_button_toggled": self.advanced_radio_select,
+            "on_info_button_button_press_event": self.on_help_button,
+            "on_back_button_clicked": self.on_help_back_clicked,
+            "on_forward_button_clicked": self.on_help_forward_clicked,
+            "on_Boolean_treeview_columns_changed": self.resize_columns,
+            "on_completion_entry_changed": self.application_selected,
+            "on_Add_button_clicked": self.add_button_clicked,
+            "on_Delete_button_clicked": self.delete_button_clicked,
+            "on_Modify_button_clicked": self.modify_button_clicked,
+            "on_Show_modified_only_toggled": self.on_show_modified_only,
+            "on_cancel_button_config_clicked": self.close_config_window,
+            "on_Import_button_clicked": self.import_config_show,
+            "on_Export_button_clicked": self.export_config_show,
+            "on_enable_unconfined_toggled": self.unconfined_toggle,
+            "on_enable_permissive_toggled": self.permissive_toggle,
+            "on_system_policy_type_combobox_changed": self.change_default_policy,
+            "on_Enforcing_button_default_toggled": self.change_default_mode,
+            "on_Permissive_button_default_toggled": self.change_default_mode,
+            "on_Disabled_button_default_toggled": self.change_default_mode,
 
-               "on_Relabel_button_toggled_cb": self.relabel_on_reboot,
-               "on_advanced_system_button_press_event" : self.reveal_advanced_system,
-               "on_files_type_combobox_changed" : self.show_more_types,
-               "on_filter_row_changed" : self.filter_the_data,
-               "on_button_toggled" : self.tab_change,
-               "gtk_main_quit": self.closewindow
-               }
+            "on_Relabel_button_toggled_cb": self.relabel_on_reboot,
+            "on_advanced_system_button_press_event": self.reveal_advanced_system,
+            "on_files_type_combobox_changed": self.show_more_types,
+            "on_filter_row_changed": self.filter_the_data,
+            "on_button_toggled": self.tab_change,
+            "gtk_main_quit": self.closewindow
+        }
 
         self.previously_modified_initialize(customized)
         builder.connect_signals(dic)
         self.window.show()                # Show the gui to the screen
-        GLib.timeout_add_seconds(5,self.selinux_status)
+        GLib.timeout_add_seconds(5, self.selinux_status)
         self.selinux_status()
         self.lockdown_inited = False
         self.add_modify_delete_box.hide()
@@ -619,7 +623,7 @@
         for k in keys:
             self.cur_dict[k] = {}
 
-    def remove_cur(self,ctr):
+    def remove_cur(self, ctr):
         i = 0
         for k in self.cur_dict:
             for j in self.cur_dict[k]:
@@ -638,7 +642,7 @@
             self.current_status_enforcing.set_sensitive(False)
             self.current_status_permissive.set_sensitive(False)
             self.enforcing_button_default.set_sensitive(False)
-            self.status_bar.push(self.context_id,  _("System Status: Disabled"))
+            self.status_bar.push(self.context_id, _("System Status: Disabled"))
             self.info_text.set_label(DISABLED_TEXT)
         else:
             self.set_enforce_text(self.status)
@@ -670,7 +674,7 @@
             mod = m.split()
             if len(mod) < 2:
                 continue
-            self.module_dict[mod[0]] = { "version": mod[1], "Disabled" : (len(mod) > 2) }
+            self.module_dict[mod[0]] = {"version": mod[1], "Disabled": (len(mod) > 2)}
 
         self.enable_unconfined_button.set_active(not self.module_dict["unconfined"]["Disabled"])
         self.enable_permissive_button.set_active(not self.module_dict["permissivedomains"]["Disabled"])
@@ -719,7 +723,7 @@
         except IOError:
             buf = ""
         help_text = self.help_text.get_buffer()
-        help_text.set_text(buf % { "APP": self.application })
+        help_text.set_text(buf % {"APP": self.application})
         self.help_text.set_buffer(help_text)
         self.help_image.set_from_file("%shelp/%s.png" % (self.code_path, self.help_list[self.help_page]))
         self.show_popup(self.help_window)
@@ -737,70 +741,70 @@
         self.help_list = []
         if self.opage == START_PAGE:
             self.help_window.set_title(_("Help: Start Page"))
-            self.help_list = [ "start"]
+            self.help_list = ["start"]
 
         if self.opage == BOOLEANS_PAGE:
             self.help_window.set_title(_("Help: Booleans Page"))
-            self.help_list = [ "booleans", "booleans_toggled", "booleans_more", "booleans_more_show"]
+            self.help_list = ["booleans", "booleans_toggled", "booleans_more", "booleans_more_show"]
 
         if self.opage == FILES_PAGE:
             ipage = self.inner_notebook_files.get_current_page()
             if ipage == EXE_PAGE:
                 self.help_window.set_title(_("Help: Executable Files Page"))
-                self.help_list = [ "files_exec" ]
+                self.help_list = ["files_exec"]
             if ipage == WRITABLE_PAGE:
                 self.help_window.set_title(_("Help: Writable Files Page"))
-                self.help_list = [ "files_write" ]
+                self.help_list = ["files_write"]
             if ipage == APP_PAGE:
                 self.help_window.set_title(_("Help: Application Types Page"))
-                self.help_list = [ "files_app" ]
+                self.help_list = ["files_app"]
         if self.opage == NETWORK_PAGE:
             ipage = self.inner_notebook_network.get_current_page()
             if ipage == OUTBOUND_PAGE:
                 self.help_window.set_title(_("Help: Outbound Network Connections Page"))
-                self.help_list = [ "ports_outbound" ]
+                self.help_list = ["ports_outbound"]
             if ipage == INBOUND_PAGE:
                 self.help_window.set_title(_("Help: Inbound Network Connections Page"))
-                self.help_list = [ "ports_inbound" ]
+                self.help_list = ["ports_inbound"]
 
         if self.opage == TRANSITIONS_PAGE:
             ipage = self.inner_notebook_transitions.get_current_page()
             if ipage == TRANSITIONS_FROM_PAGE:
                 self.help_window.set_title(_("Help: Transition from application Page"))
-                self.help_list = [ "transition_from", "transition_from_boolean", "transition_from_boolean_1", "transition_from_boolean_2"]
+                self.help_list = ["transition_from", "transition_from_boolean", "transition_from_boolean_1", "transition_from_boolean_2"]
             if ipage == TRANSITIONS_TO_PAGE:
                 self.help_window.set_title(_("Help: Transition into application Page"))
-                self.help_list = [ "transition_to" ]
+                self.help_list = ["transition_to"]
             if ipage == TRANSITIONS_FILE_PAGE:
                 self.help_window.set_title(_("Help: Transition application file Page"))
-                self.help_list = [ "transition_file" ]
+                self.help_list = ["transition_file"]
 
         if self.opage == SYSTEM_PAGE:
-                self.help_window.set_title(_("Help: Systems Page"))
-                self.help_list = [ "system", "system_boot_mode", "system_current_mode", "system_export", "system_policy_type", "system_relabel" ]
+            self.help_window.set_title(_("Help: Systems Page"))
+            self.help_list = ["system", "system_boot_mode", "system_current_mode", "system_export", "system_policy_type", "system_relabel"]
 
         if self.opage == LOCKDOWN_PAGE:
-                self.help_window.set_title(_("Help: Lockdown Page"))
-                self.help_list = [ "lockdown", "lockdown_unconfined", "lockdown_permissive", "lockdown_ptrace" ]
+            self.help_window.set_title(_("Help: Lockdown Page"))
+            self.help_list = ["lockdown", "lockdown_unconfined", "lockdown_permissive", "lockdown_ptrace"]
 
         if self.opage == LOGIN_PAGE:
-                self.help_window.set_title(_("Help: Login Page"))
-                self.help_list = [ "login", "login_default" ]
+            self.help_window.set_title(_("Help: Login Page"))
+            self.help_list = ["login", "login_default"]
 
         if self.opage == USER_PAGE:
-                self.help_window.set_title(_("Help: SELinux User Page"))
-                self.help_list = [ "users" ]
+            self.help_window.set_title(_("Help: SELinux User Page"))
+            self.help_list = ["users"]
 
         if self.opage == FILE_EQUIV_PAGE:
-                self.help_window.set_title(_("Help: File Equivalence Page"))
-                self.help_list = [ "file_equiv"]
+            self.help_window.set_title(_("Help: File Equivalence Page"))
+            self.help_list = ["file_equiv"]
         return self.help_show_page()
 
     def open_combo_menu(self, *args):
         if self.popup == 0:
             self.popup = 1
             location = self.window.get_position()
-            self.main_selection_window.move(location[0]+2, location[1]+65)
+            self.main_selection_window.move(location[0] + 2, location[1] + 65)
             self.main_selection_window.show()
         else:
             self.main_selection_window.hide()
@@ -827,7 +831,7 @@
 
     def populate_system_policy(self):
         selinux_path = selinux.selinux_path()
-        types = map(lambda x: x[1], filter(lambda x: x[0]==selinux_path, os.walk(selinux_path)))[0]
+        types = map(lambda x: x[1], filter(lambda x: x[0] == selinux_path, os.walk(selinux_path)))[0]
         types.sort()
         ctr = 0
         for item in types:
@@ -844,23 +848,23 @@
         if self.filter_txt == "":
             return True
         try:
-            for x in range(0,list.get_n_columns()):
+            for x in range(0, list.get_n_columns()):
                 try:
                     val = list.get_value(iter, x)
                     if val == True or val == False or val == None:
                         continue
                     # Returns true if filter_txt exists within the val
-                    if(val.find(self.filter_txt) != -1 or val.lower().find(self.filter_txt) != -1) :
+                    if(val.find(self.filter_txt) != -1 or val.lower().find(self.filter_txt) != -1):
                         return True
                 except AttributeError, TypeError:
                     pass
-        except: #ValueError:
+        except:  # ValueError:
             pass
         return False
 
     def net_update(self, app, netd, protocol, direction, model):
         for k in netd.keys():
-            for t,ports in netd[k]:
+            for t, ports in netd[k]:
                 pkey = (",".join(ports), protocol)
                 if pkey in self.cur_dict["port"]:
                     if self.cur_dict["port"][pkey]["action"] == "-d":
@@ -937,7 +941,7 @@
                 return
             ctr += 1
 
-        niter = liststore.get_iter(ctr-1)
+        niter = liststore.get_iter(ctr - 1)
         if liststore.get_value(niter, 0) == _("More..."):
             iter = liststore.insert_before(niter)
             ctr = ctr - 1
@@ -1069,7 +1073,7 @@
 
     def reinit(self):
         sepolicy.reinit()
-        self.fcdict=sepolicy.get_fcdict()
+        self.fcdict = sepolicy.get_fcdict()
         self.local_file_paths = sepolicy.get_local_file_paths()
 
     def previously_modified_initialize(self, buf):
@@ -1083,36 +1087,36 @@
             if rec[0] not in self.cust_dict:
                 self.cust_dict[rec[0]] = {}
             if rec[0] == "boolean":
-                self.cust_dict["boolean"][rec[-1]] = { "active": rec[2] == "-1" }
+                self.cust_dict["boolean"][rec[-1]] = {"active": rec[2] == "-1"}
             if rec[0] == "login":
-                self.cust_dict["login"][rec[-1]] = { "seuser": rec[3], "range": rec[5] }
+                self.cust_dict["login"][rec[-1]] = {"seuser": rec[3], "range": rec[5]}
             if rec[0] == "interface":
-                self.cust_dict["interface"][rec[-1]] = { "type": rec[3] }
+                self.cust_dict["interface"][rec[-1]] = {"type": rec[3]}
             if rec[0] == "user":
-                self.cust_dict["user"][rec[-1]] = { "level": "s0", "range": rec[3], "role": rec[5] }
+                self.cust_dict["user"][rec[-1]] = {"level": "s0", "range": rec[3], "role": rec[5]}
             if rec[0] == "port":
-                self.cust_dict["port"][(rec[-1], rec[-2] )] = { "type": rec[3] }
+                self.cust_dict["port"][(rec[-1], rec[-2])] = {"type": rec[3]}
             if rec[0] == "node":
-                self.cust_dict["node"][rec[-1]] = { "mask": rec[3], "protocol":rec[5], "type": rec[7] }
+                self.cust_dict["node"][rec[-1]] = {"mask": rec[3], "protocol": rec[5], "type": rec[7]}
             if rec[0] == "fcontext":
                 if rec[2] == "-e":
                     if "fcontext-equiv" not in self.cust_dict:
                         self.cust_dict["fcontext-equiv"] = {}
-                    self.cust_dict["fcontext-equiv"][(rec[-1])] = { "equiv": rec[3] }
+                    self.cust_dict["fcontext-equiv"][(rec[-1])] = {"equiv": rec[3]}
                 else:
-                    self.cust_dict["fcontext"][(rec[-1],rec[3])] = { "type": rec[5] }
+                    self.cust_dict["fcontext"][(rec[-1], rec[3])] = {"type": rec[5]}
             if rec[0] == "module":
-                self.cust_dict["module"][rec[-1]] = { "enabled": rec[2] != "-d" }
+                self.cust_dict["module"][rec[-1]] = {"enabled": rec[2] != "-d"}
 
         if "module" not in self.cust_dict:
             return
-        for semodule, button in [ ("unconfined", self.disable_unconfined_button), ("permissivedomains", self.disable_permissive_button) ]:
+        for semodule, button in [("unconfined", self.disable_unconfined_button), ("permissivedomains", self.disable_permissive_button)]:
             if semodule in self.cust_dict["module"]:
                 button.set_active(self.cust_dict["module"][semodule]["enabled"])
 
         for i in keys:
             if i not in self.cust_dict:
-                self.cust_dict.update({i:{}})
+                self.cust_dict.update({i: {}})
 
     def executable_files_initialize(self, application):
         self.entrypoints = sepolicy.get_entrypoints(application)
@@ -1130,7 +1134,7 @@
 
     def mislabeled(self, path):
         try:
-            con = selinux.matchpathcon(path,0)[1]
+            con = selinux.matchpathcon(path, 0)[1]
             cur = selinux.getfilecon(path)[1]
             return con != cur
         except OSError:
@@ -1139,9 +1143,9 @@
     def set_mislabeled(self, tree, path, iter, niter):
         if not self.mislabeled(path):
             return
-        con = selinux.matchpathcon(path,0)[1]
+        con = selinux.matchpathcon(path, 0)[1]
         cur = selinux.getfilecon(path)[1]
-        self.mislabeled_files=True
+        self.mislabeled_files = True
         # Set visibility of label
         tree.set_value(niter, 3, True)
         # Has a mislabel
@@ -1159,8 +1163,8 @@
                 continue
             file_class = self.writable_files[write][1]
             for path in self.writable_files[write][0]:
-                if (path,file_class) in self.cur_dict["fcontext"]:
-                    if self.cur_dict["fcontext"][(path,file_class) ]["action"] == "-d":
+                if (path, file_class) in self.cur_dict["fcontext"]:
+                    if self.cur_dict["fcontext"][(path, file_class)]["action"] == "-d":
                         continue
                     if write != self.cur_dict["fcontext"][(path, file_class)]["type"]:
                         continue
@@ -1172,7 +1176,7 @@
             path = _("MISSING FILE PATH")
             modify = False
         else:
-            modify = (path,file_class) in self.local_file_paths
+            modify = (path, file_class) in self.local_file_paths
             for p in sepolicy.find_file(path):
                 niter = liststore.append(iter)
                 liststore.set_value(niter, 0, p)
@@ -1191,7 +1195,7 @@
 
     def unmarkup(self, f):
         if f:
-            return re.sub("</b>$","", re.sub("^<b>","", f))
+            return re.sub("</b>$", "", re.sub("^<b>", "", f))
         return None
 
     def application_files_initialize(self, application):
@@ -1201,7 +1205,7 @@
                 continue
             file_class = self.file_types[app][1]
             for path in self.file_types[app][0]:
-                desc = sepolicy.get_description(app, markup = self.markup)
+                desc = sepolicy.get_description(app, markup=self.markup)
                 if (path, file_class) in self.cur_dict["fcontext"]:
                     if self.cur_dict["fcontext"][(path, file_class)]["action"] == "-d":
                         continue
@@ -1222,7 +1226,7 @@
                 if b in self.cur_dict["boolean"]:
                     active = self.cur_dict["boolean"][b]['active']
                 desc = sepolicy.boolean_desc(b)
-                self.boolean_initial_data_insert(b, desc , active)
+                self.boolean_initial_data_insert(b, desc, active)
 
     def boolean_initial_data_insert(self, val, desc, active):
         # Insert data from data source into tree
@@ -1350,9 +1354,9 @@
             elif ipage == APP_PAGE:
                 self.treeview = self.application_files_treeview
                 category = _("application")
-            self.add_button.set_tooltip_text(_("Add new %(TYPE)s file path for '%(DOMAIN)s' domains.") % { "TYPE": category, "DOMAIN": self.application})
-            self.delete_button.set_tooltip_text(_("Delete %(TYPE)s file paths for '%(DOMAIN)s' domain.") % { "TYPE": category, "DOMAIN": self.application})
-            self.modify_button.set_tooltip_text(_("Modify %(TYPE)s file path for '%(DOMAIN)s' domain. Only bolded items in the list can be selected, this indicates they were modified previously.") % { "TYPE": category, "DOMAIN": self.application})
+            self.add_button.set_tooltip_text(_("Add new %(TYPE)s file path for '%(DOMAIN)s' domains.") % {"TYPE": category, "DOMAIN": self.application})
+            self.delete_button.set_tooltip_text(_("Delete %(TYPE)s file paths for '%(DOMAIN)s' domain.") % {"TYPE": category, "DOMAIN": self.application})
+            self.modify_button.set_tooltip_text(_("Modify %(TYPE)s file path for '%(DOMAIN)s' domain. Only bolded items in the list can be selected, this indicates they were modified previously.") % {"TYPE": category, "DOMAIN": self.application})
 
         if self.network_radio_button.get_active():
             self.add_modify_delete_box.show()
@@ -1428,11 +1432,11 @@
             self.treesort = self.treeview.get_model()
             self.treefilter = self.treesort.get_model()
             self.liststore = self.treefilter.get_model()
-            for x in range(0,self.liststore.get_n_columns()):
+            for x in range(0, self.liststore.get_n_columns()):
                 col = self.treeview.get_column(x)
                 if col:
                     cell = col.get_cells()[0]
-                    if isinstance(cell,Gtk.CellRendererText):
+                    if isinstance(cell, Gtk.CellRendererText):
                         self.liststore.set_sort_func(x, self.stripsort, None)
             self.treeview.get_selection().unselect_all()
         self.modify_button.set_sensitive(False)
@@ -1441,7 +1445,7 @@
         sort_column, _ = model.get_sort_column_id()
         val1 = self.unmarkup(model.get_value(row1, sort_column))
         val2 = self.unmarkup(model.get_value(row2, sort_column))
-        return cmp(val1,val2)
+        return cmp(val1, val2)
 
     def display_more_detail(self, windows, path):
         it = self.boolean_filter.get_iter(path)
@@ -1449,7 +1453,7 @@
 
         self.boolean_more_detail_tree_data_set.clear()
         self.boolean_more_detail_window.set_title(_("Boolean %s Allow Rules") % self.boolean_liststore.get_value(it, 2))
-        blist = sepolicy.get_boolean_rules(self.application,self.boolean_liststore.get_value(it, 2));
+        blist = sepolicy.get_boolean_rules(self.application, self.boolean_liststore.get_value(it, 2))
         for b in blist:
             self.display_more_detail_init(b["source"], b["target"], b["class"], b["permlist"])
         self.show_popup(self.boolean_more_detail_window)
@@ -1461,14 +1465,14 @@
     def add_button_clicked(self, *args):
         self.modify = False
         if self.opage == NETWORK_PAGE:
-            self.popup_network_label.set_text((_("Add Network Port for %s.  Ports will be created when update is applied."))% self.application)
-            self.network_popup_window.set_title((_("Add Network Port for %s"))% self.application)
+            self.popup_network_label.set_text((_("Add Network Port for %s.  Ports will be created when update is applied.")) % self.application)
+            self.network_popup_window.set_title((_("Add Network Port for %s")) % self.application)
             self.init_network_dialog(args)
             return
 
         if self.opage == FILES_PAGE:
-            self.popup_files_label.set_text((_("Add File Labeling for %s. File labels will be created when update is applied."))% self.application)
-            self.files_popup_window.set_title((_("Add File Labeling for %s"))% self.application)
+            self.popup_files_label.set_text((_("Add File Labeling for %s. File labels will be created when update is applied.")) % self.application)
+            self.files_popup_window.set_title((_("Add File Labeling for %s")) % self.application)
             self.init_files_dialog(args)
             ipage = self.inner_notebook_files.get_current_page()
             if ipage == EXE_PAGE:
@@ -1520,8 +1524,8 @@
             self.modify_button_network_clicked(args)
 
         if self.opage == FILES_PAGE:
-            self.popup_files_label.set_text((_("Modify File Labeling for %s. File labels will be created when update is applied."))% self.application)
-            self.files_popup_window.set_title((_("Add File Labeling for %s"))% self.application)
+            self.popup_files_label.set_text((_("Modify File Labeling for %s. File labels will be created when update is applied.")) % self.application)
+            self.files_popup_window.set_title((_("Add File Labeling for %s")) % self.application)
             self.delete_old_item = None
             self.init_files_dialog(args)
             self.modify = True
@@ -1572,26 +1576,26 @@
 
         if self.opage == USER_PAGE:
             self.user_init_dialog(args)
-            self.user_name_entry.set_text(self.user_liststore.get_value(iter,0))
-            self.user_mls_level_entry.set_text(self.user_liststore.get_value(iter,2))
-            self.user_mls_entry.set_text(self.user_liststore.get_value(iter,3))
-            self.combo_set_active_text(self.user_roles_combobox, self.user_liststore.get_value(iter,1))
+            self.user_name_entry.set_text(self.user_liststore.get_value(iter, 0))
+            self.user_mls_level_entry.set_text(self.user_liststore.get_value(iter, 2))
+            self.user_mls_entry.set_text(self.user_liststore.get_value(iter, 3))
+            self.combo_set_active_text(self.user_roles_combobox, self.user_liststore.get_value(iter, 1))
             self.user_label.set_text((_("Modify SELinux User Role. SELinux user roles will be modified when update is applied.")))
             self.user_popup_window.set_title(_("Modify SELinux Users"))
             self.show_popup(self.user_popup_window)
 
         if self.opage == LOGIN_PAGE:
             self.login_init_dialog(args)
-            self.login_name_entry.set_text(self.login_liststore.get_value(iter,0))
-            self.login_mls_entry.set_text(self.login_liststore.get_value(iter,2))
-            self.combo_set_active_text(self.login_seuser_combobox, self.login_liststore.get_value(iter,1))
+            self.login_name_entry.set_text(self.login_liststore.get_value(iter, 0))
+            self.login_mls_entry.set_text(self.login_liststore.get_value(iter, 2))
+            self.combo_set_active_text(self.login_seuser_combobox, self.login_liststore.get_value(iter, 1))
             self.login_label.set_text((_("Modify Login Mapping. Login Mapping will be modified when Update is applied.")))
             self.login_popup_window.set_title(_("Modify Login Mapping"))
             self.show_popup(self.login_popup_window)
 
         if self.opage == FILE_EQUIV_PAGE:
-            self.file_equiv_source_entry.set_text(self.file_equiv_liststore.get_value(iter,0))
-            self.file_equiv_dest_entry.set_text(self.file_equiv_liststore.get_value(iter,1))
+            self.file_equiv_source_entry.set_text(self.file_equiv_liststore.get_value(iter, 0))
+            self.file_equiv_dest_entry.set_text(self.file_equiv_liststore.get_value(iter, 1))
             self.file_equiv_label.set_text((_("Modify File Equivalency Mapping. Mapping will be created when update is applied.")))
             self.file_equiv_popup_window.set_title(_("Modify SELinux File Equivalency"))
             self.clear_entry = True
@@ -1608,9 +1612,9 @@
         if domain == None:
             return
         if domain.endswith("_script_t"):
-            split_char="_script_t"
+            split_char = "_script_t"
         else:
-            split_char="_t"
+            split_char = "_t"
         return domain.split(split_char)[0]
 
     def exclude_type(self, type, exclude_list):
@@ -1678,8 +1682,8 @@
             self.modify_button.set_sensitive(False)
             return
 
-        self.popup_network_label.set_text((_("Modify Network Port for %s.  Ports will be created when update is applied."))% self.application)
-        self.network_popup_window.set_title((_("Modify Network Port for %s"))% self.application)
+        self.popup_network_label.set_text((_("Modify Network Port for %s.  Ports will be created when update is applied.")) % self.application)
+        self.network_popup_window.set_title((_("Modify Network Port for %s")) % self.application)
         self.delete_old_item = None
         self.init_network_dialog(args)
         operation = "Modify"
@@ -1713,7 +1717,7 @@
 
             port_types = []
             for k in netd.keys():
-                for t,ports in netd[k]:
+                for t, ports in netd[k]:
                     if t not in port_types + ["port_t", "unreserved_port_t"]:
                         if t.endswith("_type"):
                             continue
@@ -1813,9 +1817,10 @@
 
     def on_show_modified_only(self, checkbutton):
         length = self.liststore.get_n_columns()
+
         def dup_row(row):
             l = []
-            for i in range(0,length):
+            for i in range(0, length):
                 l.append(row[i])
             return l
 
@@ -1838,7 +1843,7 @@
                 if ipage == APP_PAGE:
                     return self.application_files_initialize(self.application)
             for row in self.liststore:
-                if (row[0],row[2]) in self.cust_dict["fcontext"]:
+                if (row[0], row[2]) in self.cust_dict["fcontext"]:
                     append_list.append(row)
 
         if self.opage == NETWORK_PAGE:
@@ -1875,7 +1880,7 @@
         self.liststore.clear()
         for row in append_list:
             iter = self.liststore.append()
-            for i in range(0,length):
+            for i in range(0, length):
                 self.liststore.set_value(iter, i, row[i])
 
     def init_modified_files_liststore(self, tree, app, ipage, operation, path, fclass, ftype):
@@ -1927,20 +1932,20 @@
         name = self.login_name_entry.get_text()
         if self.modify:
             iter = self.get_selected_iter()
-            oldname = self.login_liststore.get_value(iter,0)
-            oldseuser = self.login_liststore.get_value(iter,1)
-            oldrange = self.login_liststore.get_value(iter,2)
-            self.liststore.set_value(iter,0,oldname)
-            self.liststore.set_value(iter,1,oldseuser)
-            self.liststore.set_value(iter,2,oldrange)
-            self.cur_dict["login"][name] = { "action": "-m", "range": mls_range, "seuser": seuser, "oldrange": oldrange, "oldseuser": oldseuser, "oldname": oldname }
+            oldname = self.login_liststore.get_value(iter, 0)
+            oldseuser = self.login_liststore.get_value(iter, 1)
+            oldrange = self.login_liststore.get_value(iter, 2)
+            self.liststore.set_value(iter, 0, oldname)
+            self.liststore.set_value(iter, 1, oldseuser)
+            self.liststore.set_value(iter, 2, oldrange)
+            self.cur_dict["login"][name] = {"action": "-m", "range": mls_range, "seuser": seuser, "oldrange": oldrange, "oldseuser": oldseuser, "oldname": oldname}
         else:
             iter = self.liststore.append(None)
-            self.cur_dict["login"][name] = { "action": "-a", "range": mls_range, "seuser": seuser }
+            self.cur_dict["login"][name] = {"action": "-a", "range": mls_range, "seuser": seuser}
 
-        self.liststore.set_value(iter,0,name)
-        self.liststore.set_value(iter,1,seuser)
-        self.liststore.set_value(iter,2, mls_range)
+        self.liststore.set_value(iter, 0, name)
+        self.liststore.set_value(iter, 1, seuser)
+        self.liststore.set_value(iter, 2, mls_range)
 
         self.new_updates()
 
@@ -1952,18 +1957,18 @@
         name = self.user_name_entry.get_text()
         if self.modify:
             iter = self.get_selected_iter()
-            oldname = self.user_liststore.get_value(iter,0)
-            oldroles = self.user_liststore.get_value(iter,1)
-            oldlevel = self.user_liststore.get_value(iter,1)
-            oldrange = self.user_liststore.get_value(iter,3)
-            self.liststore.set_value(iter,0,oldname)
-            self.liststore.set_value(iter,1,oldroles)
-            self.liststore.set_value(iter,2,oldlevel)
-            self.liststore.set_value(iter,3,oldrange)
-            self.cur_dict["user"][name] = { "action": "-m", "range": mls_range, "level": level, "role":roles, "oldrange": oldrange, "oldlevel": oldlevel, "oldroles": oldroles, "oldname": oldname }
+            oldname = self.user_liststore.get_value(iter, 0)
+            oldroles = self.user_liststore.get_value(iter, 1)
+            oldlevel = self.user_liststore.get_value(iter, 1)
+            oldrange = self.user_liststore.get_value(iter, 3)
+            self.liststore.set_value(iter, 0, oldname)
+            self.liststore.set_value(iter, 1, oldroles)
+            self.liststore.set_value(iter, 2, oldlevel)
+            self.liststore.set_value(iter, 3, oldrange)
+            self.cur_dict["user"][name] = {"action": "-m", "range": mls_range, "level": level, "role": roles, "oldrange": oldrange, "oldlevel": oldlevel, "oldroles": oldroles, "oldname": oldname}
         else:
             iter = self.liststore.append(None)
-            self.cur_dict["user"][name] = { "action": "-a", "range": mls_range, "level": level, "role": roles}
+            self.cur_dict["user"][name] = {"action": "-a", "range": mls_range, "level": level, "role": roles}
 
         self.liststore.set_value(iter, 0, name)
         self.liststore.set_value(iter, 1, roles)
@@ -1978,14 +1983,14 @@
         src = self.file_equiv_source_entry.get_text()
         if self.modify:
             iter = self.get_selected_iter()
-            olddest = self.unmarkup(self.liststore.set_value(iter,0))
-            oldsrc = self.unmarkup(self.liststore.set_value(iter,1))
-            self.cur_dict["fcontext-equiv"][dest] = { "action": "-m", "src": src, "oldsrc": oldsrc, "olddest": olddest }
+            olddest = self.unmarkup(self.liststore.set_value(iter, 0))
+            oldsrc = self.unmarkup(self.liststore.set_value(iter, 1))
+            self.cur_dict["fcontext-equiv"][dest] = {"action": "-m", "src": src, "oldsrc": oldsrc, "olddest": olddest}
         else:
             iter = self.liststore.append(None)
-            self.cur_dict["fcontext-equiv"][dest] = { "action": "-a", "src": src }
-        self.liststore.set_value(iter,0,self.markup(dest))
-        self.liststore.set_value(iter,1,self.markup(src))
+            self.cur_dict["fcontext-equiv"][dest] = {"action": "-a", "src": src}
+        self.liststore.set_value(iter, 0, self.markup(dest))
+        self.liststore.set_value(iter, 1, self.markup(src))
 
     def update_to_files(self, *args):
         self.close_popup()
@@ -2004,10 +2009,10 @@
             oldpath = self.unmark(self.liststore.get_value(iter, 0))
             setype = self.unmark(self.liststore.set_value(iter, 1))
             oldtclass = self.liststore.get_value(iter, 2)
-            self.cur_dict["fcontext"][(path, tclass)] = { "action": "-m", "type": setype, "oldtype": oldsetype, "oldmls": oldmls, "oldclass": oldclass }
+            self.cur_dict["fcontext"][(path, tclass)] = {"action": "-m", "type": setype, "oldtype": oldsetype, "oldmls": oldmls, "oldclass": oldclass}
         else:
             iter = self.liststore.append(None)
-            self.cur_dict["fcontext"][(path, tclass)] = { "action": "-a", "type": setype }
+            self.cur_dict["fcontext"][(path, tclass)] = {"action": "-a", "type": setype}
         self.liststore.set_value(iter, 0, self.markup(path))
         self.liststore.set_value(iter, 1, self.markup(setype))
         self.liststore.set_value(iter, 2, self.markup(tclass))
@@ -2034,10 +2039,10 @@
             oldports = self.unmark(self.liststore.get_value(iter, 0))
             oldprotocol = self.unmark(self.liststore.get_value(iter, 1))
             oldsetype = self.unmark(self.liststore.set_value(iter, 2))
-            self.cur_dict["port"][(ports, protocol)] = { "action": "-m", "type": setype, "mls": mls, "oldtype": oldsetype, "oldmls": oldmls, "oldprotocol": oldprotocol, "oldports": oldports }
+            self.cur_dict["port"][(ports, protocol)] = {"action": "-m", "type": setype, "mls": mls, "oldtype": oldsetype, "oldmls": oldmls, "oldprotocol": oldprotocol, "oldports": oldports}
         else:
             iter = self.liststore.append(None)
-            self.cur_dict["port"][(ports, protocol)] = { "action": "-a", "type": setype, "mls": mls}
+            self.cur_dict["port"][(ports, protocol)] = {"action": "-a", "type": setype, "mls": mls}
         self.liststore.set_value(iter, 0, ports)
         self.liststore.set_value(iter, 1, protocol)
         self.liststore.set_value(iter, 2, setype)
@@ -2053,7 +2058,7 @@
         if self.opage == NETWORK_PAGE:
             self.network_delete_liststore.clear()
             port_dict = self.cust_dict["port"]
-            for ports,protocol in port_dict:
+            for ports, protocol in port_dict:
                 setype = port_dict[(ports, protocol)]["type"]
                 iter = self.network_delete_liststore.append()
                 self.network_delete_liststore.set_value(iter, 1, ports)
@@ -2065,7 +2070,7 @@
         if self.opage == FILES_PAGE:
             self.files_delete_liststore.clear()
             fcontext_dict = self.cust_dict["fcontext"]
-            for path,tclass in fcontext_dict:
+            for path, tclass in fcontext_dict:
                 setype = fcontext_dict[(path, tclass)]["type"]
                 iter = self.files_delete_liststore.append()
                 self.files_delete_liststore.set_value(iter, 1, path)
@@ -2117,23 +2122,23 @@
         if self.opage == NETWORK_PAGE:
             for delete in self.network_delete_liststore:
                 if delete[0]:
-                    self.cur_dict["port"][(delete[1], delete[2])] = { "action": "-d", "type": delete[3] }
+                    self.cur_dict["port"][(delete[1], delete[2])] = {"action": "-d", "type": delete[3]}
         if self.opage == FILES_PAGE:
             for delete in self.files_delete_liststore:
                 if delete[0]:
-                    self.cur_dict["fcontext"][(delete[1], reverse_file_type_str[delete[3]])] = { "action": "-d", "type": delete[2] }
+                    self.cur_dict["fcontext"][(delete[1], reverse_file_type_str[delete[3]])] = {"action": "-d", "type": delete[2]}
         if self.opage == USER_PAGE:
             for delete in self.user_delete_liststore:
                 if delete[0]:
-                    self.cur_dict["user"][delete[1]] = { "action": "-d" , "role": delete[2], "range": delete[4] }
+                    self.cur_dict["user"][delete[1]] = {"action": "-d", "role": delete[2], "range": delete[4]}
         if self.opage == LOGIN_PAGE:
             for delete in self.login_delete_liststore:
                 if delete[0]:
-                    self.cur_dict["login"][delete[2]] = { "action": "-d", "login":delete[2], "seuser":delete[1], "range":delete[3] }
+                    self.cur_dict["login"][delete[2]] = {"action": "-d", "login": delete[2], "seuser": delete[1], "range": delete[3]}
         if self.opage == FILE_EQUIV_PAGE:
             for delete in self.file_equiv_delete_liststore:
                 if delete[0]:
-                    self.cur_dict["fcontext-equiv"][delete[1]] = { "action": "-d", "src" : delete[2] }
+                    self.cur_dict["fcontext-equiv"][delete[1]] = {"action": "-d", "src": delete[2]}
         self.new_updates()
 
     def on_save_delete_file_equiv_clicked(self, *args):
@@ -2150,7 +2155,7 @@
                 iter = liststore.get_iter(ctr)
                 liststore.remove(iter)
                 return
-            ctr+=1
+            ctr += 1
 
     def on_toggle(self, cell, path, model):
         if not path:
@@ -2163,7 +2168,7 @@
         if name in self.cur_dict["boolean"]:
             del(self.cur_dict["boolean"][name])
         else:
-            self.cur_dict["boolean"][name] = {"active":active}
+            self.cur_dict["boolean"][name] = {"active": active}
         self.new_updates()
 
     def get_advanced_filter_data(self, entry, *args):
@@ -2183,60 +2188,60 @@
             operation = self.cur_dict["boolean"][bools]["action"]
             iter = self.update_treestore.append(None)
             self.update_treestore.set_value(iter, 0, True)
-            self.update_treestore.set_value(iter, 1,  sepolicy.boolean_desc(bools))
+            self.update_treestore.set_value(iter, 1, sepolicy.boolean_desc(bools))
             self.update_treestore.set_value(iter, 2, action[self.cur_dict["boolean"][bools]['active']])
             self.update_treestore.set_value(iter, 3, True)
             niter = self.update_treestore.append(iter)
-            self.update_treestore.set_value(niter, 1, (_("SELinux name: %s"))% bools)
+            self.update_treestore.set_value(niter, 1, (_("SELinux name: %s")) % bools)
             self.update_treestore.set_value(niter, 3, False)
 
-        for path,tclass in self.cur_dict["fcontext"]:
-            operation = self.cur_dict["fcontext"][(path,tclass)]["action"]
-            setype = self.cur_dict["fcontext"][(path,tclass)]["type"]
+        for path, tclass in self.cur_dict["fcontext"]:
+            operation = self.cur_dict["fcontext"][(path, tclass)]["action"]
+            setype = self.cur_dict["fcontext"][(path, tclass)]["type"]
             iter = self.update_treestore.append(None)
             self.update_treestore.set_value(iter, 0, True)
             self.update_treestore.set_value(iter, 2, operation)
             self.update_treestore.set_value(iter, 0, True)
             if operation == "-a":
-                self.update_treestore.set_value(iter, 1, (_("Add file labeling for %s"))% self.application)
+                self.update_treestore.set_value(iter, 1, (_("Add file labeling for %s")) % self.application)
             if operation == "-d":
-                self.update_treestore.set_value(iter, 1, (_("Delete file labeling for %s"))% self.application)
+                self.update_treestore.set_value(iter, 1, (_("Delete file labeling for %s")) % self.application)
             if operation == "-m":
-                self.update_treestore.set_value(iter, 1, (_("Modify file labeling for %s"))% self.application)
+                self.update_treestore.set_value(iter, 1, (_("Modify file labeling for %s")) % self.application)
 
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
-            self.update_treestore.set_value(niter, 1, (_("File path: %s"))% path)
+            self.update_treestore.set_value(niter, 1, (_("File path: %s")) % path)
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
-            self.update_treestore.set_value(niter, 1, (_("File class: %s"))% sepolicy.file_type_str[tclass])
+            self.update_treestore.set_value(niter, 1, (_("File class: %s")) % sepolicy.file_type_str[tclass])
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
-            self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s"))% setype)
+            self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s")) % setype)
 
-        for port,protocol in self.cur_dict["port"]:
-            operation = self.cur_dict["port"][(port,protocol)]["action"]
+        for port, protocol in self.cur_dict["port"]:
+            operation = self.cur_dict["port"][(port, protocol)]["action"]
             iter = self.update_treestore.append(None)
             self.update_treestore.set_value(iter, 0, True)
             self.update_treestore.set_value(iter, 2, operation)
             self.update_treestore.set_value(iter, 3, True)
             if operation == "-a":
-                self.update_treestore.set_value(iter, 1, (_("Add ports for %s"))% self.application)
+                self.update_treestore.set_value(iter, 1, (_("Add ports for %s")) % self.application)
             if operation == "-d":
-                self.update_treestore.set_value(iter, 1, (_("Delete ports for %s"))% self.application)
+                self.update_treestore.set_value(iter, 1, (_("Delete ports for %s")) % self.application)
             if operation == "-m":
-                self.update_treestore.set_value(iter, 1, (_("Modify ports for %s"))% self.application)
+                self.update_treestore.set_value(iter, 1, (_("Modify ports for %s")) % self.application)
 
             niter = self.update_treestore.append(iter)
-            self.update_treestore.set_value(niter, 1, (_("Network ports: %s"))% port)
+            self.update_treestore.set_value(niter, 1, (_("Network ports: %s")) % port)
             self.update_treestore.set_value(niter, 3, False)
             niter = self.update_treestore.append(iter)
-            self.update_treestore.set_value(niter, 1, (_("Network protocol: %s"))% protocol)
+            self.update_treestore.set_value(niter, 1, (_("Network protocol: %s")) % protocol)
             self.update_treestore.set_value(niter, 3, False)
             setype = self.cur_dict["port"][(port, protocol)]["type"]
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
-            self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s"))% setype)
+            self.update_treestore.set_value(niter, 1, (_("SELinux file type: %s")) % setype)
 
         for user in self.cur_dict["user"]:
             operation = self.cur_dict["user"][user]["action"]
@@ -2252,7 +2257,7 @@
                 self.update_treestore.set_value(iter, 1, _("Modify user"))
 
             niter = self.update_treestore.append(iter)
-            self.update_treestore.set_value(niter, 1, (_("SELinux User : %s"))% user)
+            self.update_treestore.set_value(niter, 1, (_("SELinux User : %s")) % user)
             self.update_treestore.set_value(niter, 3, False)
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
@@ -2278,7 +2283,7 @@
 
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
-            self.update_treestore.set_value(niter, 1, (_("Login Name : %s"))% login)
+            self.update_treestore.set_value(niter, 1, (_("Login Name : %s")) % login)
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
             seuser = self.cur_dict["login"][login]["seuser"]
@@ -2303,7 +2308,7 @@
 
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
-            self.update_treestore.set_value(niter, 1, (_("File path : %s"))% path)
+            self.update_treestore.set_value(niter, 1, (_("File path : %s")) % path)
             niter = self.update_treestore.append(iter)
             self.update_treestore.set_value(niter, 3, False)
             src = self.cur_dict["fcontext-equiv"][path]["src"]
@@ -2394,7 +2399,7 @@
                 if iter != None:
                     if self.liststore.get_value(iter, 4) == False:
                         iterlist.append(iter)
-                    ctr +=1
+                    ctr += 1
             for iters in iterlist:
                 self.liststore.remove(iters)
 
@@ -2409,8 +2414,8 @@
 
     def fix_mislabeled(self, path):
         cur = selinux.getfilecon(path)[1].split(":")[2]
-        con = selinux.matchpathcon(path,0)[1].split(":")[2]
-        if self.verify(_("Run restorecon on %(PATH)s to change its type from %(CUR_CONTEXT)s to the default %(DEF_CONTEXT)s?") % {"PATH":path, "CUR_CONTEXT": cur, "DEF_CONTEXT": con}, title="restorecon dialog") == Gtk.ResponseType.YES:
+        con = selinux.matchpathcon(path, 0)[1].split(":")[2]
+        if self.verify(_("Run restorecon on %(PATH)s to change its type from %(CUR_CONTEXT)s to the default %(DEF_CONTEXT)s?") % {"PATH": path, "CUR_CONTEXT": cur, "DEF_CONTEXT": con}, title="restorecon dialog") == Gtk.ResponseType.YES:
             self.dbus.restorecon(path)
             self.application_selected()
 
@@ -2511,8 +2516,8 @@
 
     def revert_data(self):
         ctr = 0
-        remove_list=[]
-        update_buffer =  ""
+        remove_list = []
+        update_buffer = ""
         for items in self.update_treestore:
             if not self.update_treestore[ctr][0]:
                 remove_list.append(ctr)
@@ -2562,7 +2567,7 @@
         # From entry_point = 0 to the number of keys in the dic
         for exe in entrypoints:
             if len(entrypoints[exe]):
-                file_class  = entrypoints[exe][1]
+                file_class = entrypoints[exe][1]
                 for path in entrypoints[exe][0]:
                     iter = self.advanced_search_liststore.append()
                     self.advanced_search_liststore.set_value(iter, 1, domain)
@@ -2597,7 +2602,7 @@
 
     def set_enforce_text(self, value):
         if value:
-           self.status_bar.push(self.context_id, _("System Status: Enforcing"))
+            self.status_bar.push(self.context_id, _("System Status: Enforcing"))
         else:
             self.status_bar.push(self.context_id, _("System Status: Permissive"))
         self.current_status_permissive.set_active(True)
@@ -2622,7 +2627,7 @@
         path = self.files_path_entry.get_text()
         if self.recursive_path_toggle.get_active():
             if not path.endswith("(/.*)?"):
-                self.files_path_entry.set_text(path+"(/.*)?")
+                self.files_path_entry.set_text(path + "(/.*)?")
         elif path.endswith("(/.*)?"):
             path = path.split("(/.*)?")[0]
             self.files_path_entry.set_text(path)
@@ -2709,9 +2714,9 @@
 
     def init_dictionary(self, dic, app, ipage, operation, p, q, ftype, mls, changed, old):
         if (app, ipage, operation) not in dic:
-                    dic[app, ipage, operation] = {}
+            dic[app, ipage, operation] = {}
         if (p, q) not in dic[app, ipage, operation]:
-                    dic[app, ipage, operation][p, q] = {'type': ftype, 'mls': mls, 'changed': changed, 'old': old}
+            dic[app, ipage, operation][p, q] = {'type': ftype, 'mls': mls, 'changed': changed, 'old': old}
 
     def translate_bool(self, b):
         b = b.split('-')[1]
@@ -2765,7 +2770,7 @@
         self.window.get_window().set_cursor(self.ready_cursor)
         self.idle_func()
 
-    def verify(self, message, title="" ):
+    def verify(self, message, title=""):
         dlg = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,
                                 Gtk.ButtonsType.YES_NO,
                                 message)
diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py
index bbabb3b..69078b0 100644
--- a/policycoreutils/sepolicy/sepolicy/interface.py
+++ b/policycoreutils/sepolicy/sepolicy/interface.py
@@ -21,17 +21,18 @@
 #                                        02111-1307  USA
 #
 #
-import re, sys
+import re
+import sys
 import sepolicy
 ADMIN_TRANSITION_INTERFACE = "_admin$"
 USER_TRANSITION_INTERFACE = "_role$"
 
-__all__ = [ 'get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_user' ,'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'get_xml_file', 'interface_compile_test' ]
+__all__ = ['get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_user', 'get_interface_dict', 'get_interface_format_text', 'get_interface_compile_format_text', 'get_xml_file', 'interface_compile_test']
 
 ##
 ## I18N
 ##
-PROGNAME="policycoreutils"
+PROGNAME = "policycoreutils"
 
 import gettext
 gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
@@ -40,11 +41,12 @@
     gettext.install(PROGNAME,
                     localedir="/usr/share/locale",
                     unicode=False,
-                    codeset = 'utf-8')
+                    codeset='utf-8')
 except IOError:
     import __builtin__
     __builtin__.__dict__['_'] = unicode
 
+
 def get_interfaces_from_xml(path):
     """ Get all interfaces from given xml file"""
     interfaces_list = []
@@ -65,6 +67,7 @@
 
     return all_interfaces
 
+
 def get_admin(path=""):
     """ Get all domains with an admin interface from installed policy."""
     """ If xml_path is specified, func returns an admin interface from specified xml file"""
@@ -86,6 +89,7 @@
 
     return admin_list
 
+
 def get_user(path=""):
     """ Get all domains with SELinux user role interface"""
     """ If xml_path is specified, func returns an user role interface from specified xml file"""
@@ -111,6 +115,8 @@
     return trans_list
 
 interface_dict = None
+
+
 def get_interface_dict(path="/usr/share/selinux/devel/policy.xml"):
     global interface_dict
     import os
@@ -126,7 +132,7 @@
 <layer name="admin">
 """
     xml_path += path
-    xml_path +="""
+    xml_path += """
 </layer>
 </policy>
 """
@@ -141,23 +147,25 @@
                 for i in m.getiterator('interface'):
                     for e in i.findall("param"):
                         param_list.append(e.get('name'))
-                    interface_dict[(i.get("name"))] = [param_list,(i.find('summary').text),"interface"]
+                    interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "interface"]
                     param_list = []
                 for i in m.getiterator('template'):
                     for e in i.findall("param"):
                         param_list.append(e.get('name'))
-                    interface_dict[(i.get("name"))] = [param_list,(i.find('summary').text),"template"]
+                    interface_dict[(i.get("name"))] = [param_list, (i.find('summary').text), "template"]
                     param_list = []
     except IOError, e:
         pass
     return interface_dict
 
-def get_interface_format_text(interface,path = "/usr/share/selinux/devel/policy.xml"):
+
+def get_interface_format_text(interface, path="/usr/share/selinux/devel/policy.xml"):
     idict = get_interface_dict(path)
     interface_text = "%s(%s) %s" % (interface, ", ".join(idict[interface][0]), " ".join(idict[interface][1].split("\n")))
 
     return interface_text
 
+
 def get_interface_compile_format_text(interfaces_dict, interface):
     from templates import test_module
     param_tmp = []
@@ -167,20 +175,23 @@
 
     return interface_text
 
+
 def generate_compile_te(interface, idict, name="compiletest"):
     from templates import test_module
     te = ""
-    te += re.sub("TEMPLATETYPE", name, test_module.te_test_module )
-    te += get_interface_compile_format_text(idict,interface)
+    te += re.sub("TEMPLATETYPE", name, test_module.te_test_module)
+    te += get_interface_compile_format_text(idict, interface)
 
     return te
 
+
 def get_xml_file(if_file):
     """ Returns xml format of interfaces for given .if policy file"""
-    import os, commands
-    basedir = os.path.dirname(if_file)+"/"
+    import os
+    import commands
+    basedir = os.path.dirname(if_file) + "/"
     filename = os.path.basename(if_file).split(".")[0]
-    rc, output=commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir+filename)
+    rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
     if rc != 0:
         sys.stderr.write("\n Could not proceed selected interface file.\n")
         sys.stderr.write("\n%s" % output)
@@ -188,12 +199,14 @@
     else:
         return output
 
-def interface_compile_test(interface, path = "/usr/share/selinux/devel/policy.xml"):
-    exclude_interfaces = ["userdom","kernel","corenet","files", "dev"]
+
+def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"):
+    exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
     exclude_interface_type = ["template"]
 
-    import commands, os
-    policy_files = {'pp':"compiletest.pp", 'te':"compiletest.te", 'fc':"compiletest.fc", 'if':"compiletest.if"}
+    import commands
+    import os
+    policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
     idict = get_interface_dict(path)
 
     if not (interface.split("_")[0] in exclude_interfaces or idict[interface][2] in exclude_interface_type):
@@ -202,7 +215,7 @@
             fd = open(policy_files['te'], "w")
             fd.write(generate_compile_te(interface, idict))
             fd.close()
-            rc, output=commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'] )
+            rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
             if rc != 0:
                 sys.stderr.write(output)
                 sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py
index ba15b2c..7de2f80 100755
--- a/policycoreutils/sepolicy/sepolicy/manpage.py
+++ b/policycoreutils/sepolicy/sepolicy/manpage.py
@@ -22,7 +22,7 @@
 #                                        02111-1307  USA
 #
 #
-__all__ = [ 'ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_domains' ]
+__all__ = ['ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_domains']
 
 import string
 import argparse
@@ -31,176 +31,193 @@
 from sepolicy import *
 
 import commands
-import sys, os, re, time
+import sys
+import os
+import re
+import time
 
-equiv_dict={ "smbd" : [ "samba" ], "httpd" : [ "apache" ], "virtd" : [ "virt", "libvirt", "svirt", "svirt_tcg", "svirt_lxc_t", "svirt_lxc_net_t" ], "named" : [ "bind" ], "fsdaemon" : [ "smartmon" ], "mdadm" : [ "raid" ] }
+equiv_dict = {"smbd": ["samba"], "httpd": ["apache"], "virtd": ["virt", "libvirt", "svirt", "svirt_tcg", "svirt_lxc_t", "svirt_lxc_net_t"], "named": ["bind"], "fsdaemon": ["smartmon"], "mdadm": ["raid"]}
 
-equiv_dirs=[ "/var" ]
+equiv_dirs = ["/var"]
 modules_dict = None
-def gen_modules_dict(path = "/usr/share/selinux/devel/policy.xml"):
-	global modules_dict
-	if modules_dict:
-		return modules_dict
 
-	import xml.etree.ElementTree
-	modules_dict = {}
-	try:
-		tree = xml.etree.ElementTree.fromstring(policy_xml(path))
-		for l in  tree.findall("layer"):
-			for m in  l.findall("module"):
-				name = m.get("name")
-				if name == "user" or name == "unconfined":
-					continue
-				if name == "unprivuser":
-					name = "user"
-				if name == "unconfineduser":
-					name = "unconfined"
-				for b in  m.findall("summary"):
-					modules_dict[name] = b.text
-	except IOError, e:
-		pass
-	return modules_dict
+
+def gen_modules_dict(path="/usr/share/selinux/devel/policy.xml"):
+    global modules_dict
+    if modules_dict:
+        return modules_dict
+
+    import xml.etree.ElementTree
+    modules_dict = {}
+    try:
+        tree = xml.etree.ElementTree.fromstring(policy_xml(path))
+        for l in tree.findall("layer"):
+            for m in l.findall("module"):
+                name = m.get("name")
+                if name == "user" or name == "unconfined":
+                    continue
+                if name == "unprivuser":
+                    name = "user"
+                if name == "unconfineduser":
+                    name = "unconfined"
+                for b in m.findall("summary"):
+                    modules_dict[name] = b.text
+    except IOError, e:
+        pass
+    return modules_dict
 
 users = None
 users_range = None
+
+
 def get_all_users_info():
-	global users
-	global users_range
-	if users and users_range:
-		return users, users_range
+    global users
+    global users_range
+    if users and users_range:
+        return users, users_range
 
-	users = []
-	users_range ={}
-	allusers = []
-	allusers_info = info(USER)
+    users = []
+    users_range = {}
+    allusers = []
+    allusers_info = info(USER)
 
-	for d in allusers_info:
-		allusers.append(d['name'])
-		users_range[d['name'].split("_")[0]] = d['range']
+    for d in allusers_info:
+        allusers.append(d['name'])
+        users_range[d['name'].split("_")[0]] = d['range']
 
-	for u in allusers:
-		if u not in [ "system_u", "root", "unconfined_u" ]:
-			users.append(u.replace("_u",""))
-	users.sort()
-	return users, users_range
+    for u in allusers:
+        if u not in ["system_u", "root", "unconfined_u"]:
+            users.append(u.replace("_u", ""))
+    users.sort()
+    return users, users_range
 
 all_entrypoints = None
+
+
 def get_entrypoints():
-	global all_entrypoints
-	if not all_entrypoints:
-		all_entrypoints =  sepolicy.info(sepolicy.ATTRIBUTE,"entry_type")[0]["types"]
-	return all_entrypoints
+    global all_entrypoints
+    if not all_entrypoints:
+        all_entrypoints = sepolicy.info(sepolicy.ATTRIBUTE, "entry_type")[0]["types"]
+    return all_entrypoints
 
 domains = None
+
+
 def gen_domains():
-	global domains
-	if domains:
-		return domains
-	domains = []
-	for d in get_all_domains():
-		found = False
-		domain = d[:-2]
+    global domains
+    if domains:
+        return domains
+    domains = []
+    for d in get_all_domains():
+        found = False
+        domain = d[:-2]
 #		if domain + "_exec_t" not in get_entrypoints():
 #			continue
-		if domain in domains:
-			continue
-		domains.append(domain)
+        if domain in domains:
+            continue
+        domains.append(domain)
 
-	for role in get_all_roles():
-		if role[:-2] in domains or role == "system_r":
-			continue
-		domains.append(role[:-2])
+    for role in get_all_roles():
+        if role[:-2] in domains or role == "system_r":
+            continue
+        domains.append(role[:-2])
 
-	domains.sort()
-	return domains
+    domains.sort()
+    return domains
 
 types = None
-def _gen_types():
-	global types
-	if types:
-		return types
-	all_types =  sepolicy.info(sepolicy.TYPE)
-	types = {}
-	for rec in all_types:
-		try:
-			types[rec["name"]] = rec["attributes"]
-		except:
-			types[rec["name"]] = []
-	return types
 
-def prettyprint(f,trim):
+
+def _gen_types():
+    global types
+    if types:
+        return types
+    all_types = sepolicy.info(sepolicy.TYPE)
+    types = {}
+    for rec in all_types:
+        try:
+            types[rec["name"]] = rec["attributes"]
+        except:
+            types[rec["name"]] = []
+    return types
+
+
+def prettyprint(f, trim):
     return " ".join(f[:-len(trim)].split("_"))
 
 # for HTML man pages
 manpage_domains = []
 manpage_roles = []
 
-fedora_releases = ["Fedora17","Fedora18"]
-rhel_releases = ["RHEL6","RHEL7"]
+fedora_releases = ["Fedora17", "Fedora18"]
+rhel_releases = ["RHEL6", "RHEL7"]
+
 
 def get_alphabet_manpages(manpage_list):
-	alphabet_manpages = dict.fromkeys(string.ascii_letters, [])
-	for i in string.ascii_letters:
-		temp = []
-		for j in manpage_list:
-			if j.split("/")[-1][0] == i:
-				temp.append(j.split("/")[-1])
+    alphabet_manpages = dict.fromkeys(string.ascii_letters, [])
+    for i in string.ascii_letters:
+        temp = []
+        for j in manpage_list:
+            if j.split("/")[-1][0] == i:
+                temp.append(j.split("/")[-1])
 
-		alphabet_manpages[i] = temp
+        alphabet_manpages[i] = temp
 
-	return alphabet_manpages
+    return alphabet_manpages
 
-def convert_manpage_to_html(html_manpage,manpage):
-	rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
-	if rc == 0:
-		print html_manpage, " has been created"
-		fd = open(html_manpage,'w')
-		fd.write(output)
-		fd.close()
+
+def convert_manpage_to_html(html_manpage, manpage):
+    rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
+    if rc == 0:
+        print html_manpage, " has been created"
+        fd = open(html_manpage, 'w')
+        fd.write(output)
+        fd.close()
+
 
 class HTMLManPages:
-	"""
-		Generate a HHTML Manpages on an given SELinux domains
-	"""
 
-	def __init__(self, manpage_roles, manpage_domains, path, os_version):
-		self.manpage_roles = get_alphabet_manpages(manpage_roles)
-		self.manpage_domains = get_alphabet_manpages(manpage_domains)
-		self.os_version = os_version
-		self.old_path = path + "/"
-		self.new_path = self.old_path + self.os_version+"/"
+    """
+            Generate a HHTML Manpages on an given SELinux domains
+    """
 
-		if self.os_version in fedora_releases or rhel_releases:
-			self.__gen_html_manpages()
-		else:
-			print("SELinux HTML man pages can not be generated for this %s" % os_version)
-			exit(1)
+    def __init__(self, manpage_roles, manpage_domains, path, os_version):
+        self.manpage_roles = get_alphabet_manpages(manpage_roles)
+        self.manpage_domains = get_alphabet_manpages(manpage_domains)
+        self.os_version = os_version
+        self.old_path = path + "/"
+        self.new_path = self.old_path + self.os_version + "/"
 
-	def __gen_html_manpages(self):
-		self._write_html_manpage()
-		self._gen_index()
-		self._gen_body()
-		self._gen_css()
+        if self.os_version in fedora_releases or rhel_releases:
+            self.__gen_html_manpages()
+        else:
+            print("SELinux HTML man pages can not be generated for this %s" % os_version)
+            exit(1)
 
-	def _write_html_manpage(self):
-		if not os.path.isdir(self.new_path):
-			os.mkdir(self.new_path)
+    def __gen_html_manpages(self):
+        self._write_html_manpage()
+        self._gen_index()
+        self._gen_body()
+        self._gen_css()
 
-		for domain in self.manpage_domains.values():
-			if len(domain):
-				for d in domain:
-					convert_manpage_to_html((self.new_path+d.split("_selinux")[0]+".html"),self.old_path+d)
+    def _write_html_manpage(self):
+        if not os.path.isdir(self.new_path):
+            os.mkdir(self.new_path)
 
-		for role in self.manpage_roles.values():
-			if len(role):
-				for r in role:
-					convert_manpage_to_html((self.new_path+r.split("_selinux")[0]+".html"),self.old_path+r)
+        for domain in self.manpage_domains.values():
+            if len(domain):
+                for d in domain:
+                    convert_manpage_to_html((self.new_path + d.split("_selinux")[0] + ".html"), self.old_path + d)
 
+        for role in self.manpage_roles.values():
+            if len(role):
+                for r in role:
+                    convert_manpage_to_html((self.new_path + r.split("_selinux")[0] + ".html"), self.old_path + r)
 
-	def _gen_index(self):
-		index = self.old_path+"index.html"
-		fd = open(index,'w')
-		fd.write("""
+    def _gen_index(self):
+        index = self.old_path + "index.html"
+        fd = open(index, 'w')
+        fd.write("""
 <html>
 <head>
     <link rel=stylesheet type="text/css" href="style.css" title="style">
@@ -219,11 +236,11 @@
 </tr></table>
 <pre>
 """)
-		for f in fedora_releases:
-			fd.write("""
-<a href=%s/%s.html>%s</a> - SELinux man pages for %s """  % (f,f,f,f))
+        for f in fedora_releases:
+            fd.write("""
+<a href=%s/%s.html>%s</a> - SELinux man pages for %s """  % (f, f, f, f))
 
-		fd.write("""
+        fd.write("""
 </pre>
 <hr>
 <h3>RHEL</h3>
@@ -233,20 +250,20 @@
 </tr></table>
 <pre>
 """)
-		for r in rhel_releases:
-			fd.write("""
-<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (r,r,r,r))
+        for r in rhel_releases:
+            fd.write("""
+<a href=%s/%s.html>%s</a> - SELinux man pages for %s """ % (r, r, r, r))
 
-		fd.write("""
+        fd.write("""
 </pre>
 	""")
-		fd.close()
-		print("%s has been created") % index
+        fd.close()
+        print("%s has been created") % index
 
-	def _gen_body(self):
-		html = self.new_path+self.os_version+".html"
-		fd = open(html,'w')
-		fd.write("""
+    def _gen_body(self):
+        html = self.new_path + self.os_version + ".html"
+        fd = open(html, 'w')
+        fd.write("""
 <html>
 <head>
 	<link rel=stylesheet type="text/css" href="../style.css" title="style">
@@ -259,65 +276,65 @@
 <td valign="middle">
 <h3>SELinux roles</h3>
 """)
-		for letter in self.manpage_roles:
-			if len(self.manpage_roles[letter]):
-				fd.write("""
+        for letter in self.manpage_roles:
+            if len(self.manpage_roles[letter]):
+                fd.write("""
 <a href=#%s_role>%s</a>"""
-			% (letter,letter))
+                         % (letter, letter))
 
-		fd.write("""
+        fd.write("""
 </td>
 </tr></table>
 <pre>
 """)
-		rolename_body = ""
-		for letter in self.manpage_roles:
-			if len(self.manpage_roles[letter]):
-				rolename_body += "<p>"
-				for r in self.manpage_roles[letter]:
-					rolename = r.split("_selinux")[0]
-					rolename_body += "<a name=%s_role></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux user\n" % (letter,rolename,rolename,rolename)
+        rolename_body = ""
+        for letter in self.manpage_roles:
+            if len(self.manpage_roles[letter]):
+                rolename_body += "<p>"
+                for r in self.manpage_roles[letter]:
+                    rolename = r.split("_selinux")[0]
+                    rolename_body += "<a name=%s_role></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux user\n" % (letter, rolename, rolename, rolename)
 
-		fd.write("""%s
+        fd.write("""%s
 </pre>
 <hr>
 <table><tr>
 <td valign="middle">
 <h3>SELinux domains</h3>"""
-% rolename_body)
+                 % rolename_body)
 
-		for letter in self.manpage_domains:
-			if len(self.manpage_domains[letter]):
-				fd.write("""
+        for letter in self.manpage_domains:
+            if len(self.manpage_domains[letter]):
+                fd.write("""
 <a href=#%s_domain>%s</a>
-			"""	% (letter,letter))
+			"""	% (letter, letter))
 
-		fd.write("""
+        fd.write("""
 </td>
 </tr></table>
 <pre>
 """)
-		domainname_body = ""
-		for letter in self.manpage_domains:
-			if len(self.manpage_domains[letter]):
-				domainname_body += "<p>"
-				for r in self.manpage_domains[letter]:
-					domainname = r.split("_selinux")[0]
-					domainname_body += "<a name=%s_domain></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux processes\n" % (letter,domainname,domainname,domainname)
+        domainname_body = ""
+        for letter in self.manpage_domains:
+            if len(self.manpage_domains[letter]):
+                domainname_body += "<p>"
+                for r in self.manpage_domains[letter]:
+                    domainname = r.split("_selinux")[0]
+                    domainname_body += "<a name=%s_domain></a><a href=%s.html>%s_selinux(8)</a> - Security Enhanced Linux Policy for the %s SELinux processes\n" % (letter, domainname, domainname, domainname)
 
-		fd.write("""%s
+        fd.write("""%s
 </pre>
 </body>
 </html>
 """ % domainname_body)
 
-		fd.close()
-		print("%s has been created") % html
+        fd.close()
+        print("%s has been created") % html
 
-	def _gen_css(self):
-		style_css = self.old_path+"style.css"
-		fd = open(style_css,'w')
-		fd.write("""
+    def _gen_css(self):
+        style_css = self.old_path + "style.css"
+        fd = open(style_css, 'w')
+        fd.write("""
 html, body {
     background-color: #fcfcfc;
     font-family: arial, sans-serif;
@@ -374,159 +391,161 @@
 }
 """)
 
-		fd.close()
-		print("%s has been created") % style_css
+        fd.close()
+        print("%s has been created") % style_css
+
 
 class ManPage:
+
     """
-	Generate a Manpage on an SELinux domain in the specified path
+        Generate a Manpage on an SELinux domain in the specified path
     """
     modules_dict = None
     enabled_str = ["Disabled", "Enabled"]
 
-    def __init__(self, domainname, path = "/tmp", root="/", source_files = False ,html = False):
-	self.html = html
-	self.source_files = source_files
-	self.root = root
-	self.portrecs = gen_port_dict()[0]
-	self.domains = gen_domains()
-	self.all_domains = get_all_domains()
-	self.all_attributes = get_all_attributes()
-	self.all_bools = get_all_bools()
-	self.all_port_types = get_all_port_types()
-	self.all_roles = get_all_roles()
-	self.all_users = get_all_users_info()[0]
-	self.all_users_range = get_all_users_info()[1]
-	self.all_file_types = get_all_file_types()
-	self.role_allows = get_all_role_allows()
-	self.types = _gen_types()
+    def __init__(self, domainname, path="/tmp", root="/", source_files=False, html=False):
+        self.html = html
+        self.source_files = source_files
+        self.root = root
+        self.portrecs = gen_port_dict()[0]
+        self.domains = gen_domains()
+        self.all_domains = get_all_domains()
+        self.all_attributes = get_all_attributes()
+        self.all_bools = get_all_bools()
+        self.all_port_types = get_all_port_types()
+        self.all_roles = get_all_roles()
+        self.all_users = get_all_users_info()[0]
+        self.all_users_range = get_all_users_info()[1]
+        self.all_file_types = get_all_file_types()
+        self.role_allows = get_all_role_allows()
+        self.types = _gen_types()
 
-	if self.source_files:
-		self.fcpath = self.root + "file_contexts"
-	else:
-		self.fcpath = self.root + selinux.selinux_file_context_path()
+        if self.source_files:
+            self.fcpath = self.root + "file_contexts"
+        else:
+            self.fcpath = self.root + selinux.selinux_file_context_path()
 
-	self.fcdict = get_fcdict(self.fcpath)
+        self.fcdict = get_fcdict(self.fcpath)
 
-	if not os.path.exists(path):
-		os.makedirs(path)
+        if not os.path.exists(path):
+            os.makedirs(path)
 
-	self.path = path
+        self.path = path
 
-	if self.source_files:
-		self.xmlpath = self.root + "policy.xml"
-	else:
-		self.xmlpath = self.root + "/usr/share/selinux/devel/policy.xml"
-	self.booleans_dict = gen_bool_dict(self.xmlpath)
+        if self.source_files:
+            self.xmlpath = self.root + "policy.xml"
+        else:
+            self.xmlpath = self.root + "/usr/share/selinux/devel/policy.xml"
+        self.booleans_dict = gen_bool_dict(self.xmlpath)
 
         self.domainname, self.short_name = gen_short_name(domainname)
 
-	self.type = self.domainname + "_t"
-	self._gen_bools()
-	self.man_page_path = "%s/%s_selinux.8" % (path, self.domainname)
-	self.fd = open(self.man_page_path, 'w')
-	if self.domainname + "_r" in self.all_roles:
-	    self.__gen_user_man_page()
-	    if self.html:
-		manpage_roles.append(self.man_page_path)
-	else:
-	    if self.html:
-		manpage_domains.append(self.man_page_path)
-	    self.__gen_man_page()
-	self.fd.close()
+        self.type = self.domainname + "_t"
+        self._gen_bools()
+        self.man_page_path = "%s/%s_selinux.8" % (path, self.domainname)
+        self.fd = open(self.man_page_path, 'w')
+        if self.domainname + "_r" in self.all_roles:
+            self.__gen_user_man_page()
+            if self.html:
+                manpage_roles.append(self.man_page_path)
+        else:
+            if self.html:
+                manpage_domains.append(self.man_page_path)
+            self.__gen_man_page()
+        self.fd.close()
 
-	for k in equiv_dict.keys():
-		if k == self.domainname:
-			for alias in equiv_dict[k]:
-				self.__gen_man_page_link(alias)
+        for k in equiv_dict.keys():
+            if k == self.domainname:
+                for alias in equiv_dict[k]:
+                    self.__gen_man_page_link(alias)
 
     def _gen_bools(self):
-	    self.bools=[]
-	    self.domainbools=[]
-	    types = [self.type]
-	    if self.domainname in equiv_dict:
-		    for t in equiv_dict[self.domainname]:
-			    if t + "_t" in self.all_domains:
-				    types.append(t+"_t")
+        self.bools = []
+        self.domainbools = []
+        types = [self.type]
+        if self.domainname in equiv_dict:
+            for t in equiv_dict[self.domainname]:
+                if t + "_t" in self.all_domains:
+                    types.append(t + "_t")
 
-	    for t in types:
-                    domainbools, bools = get_bools(t)
-                    self.bools += bools
-                    self.domainbools += domainbools
+        for t in types:
+            domainbools, bools = get_bools(t)
+            self.bools += bools
+            self.domainbools += domainbools
 
-	    self.bools.sort()
-	    self.domainbools.sort()
+        self.bools.sort()
+        self.domainbools.sort()
 
     def get_man_page_path(self):
-	    return self.man_page_path
+        return self.man_page_path
 
     def __gen_user_man_page(self):
-	self.role = self.domainname + "_r"
-	if not self.modules_dict:
-		self.modules_dict = gen_modules_dict(self.xmlpath)
+        self.role = self.domainname + "_r"
+        if not self.modules_dict:
+            self.modules_dict = gen_modules_dict(self.xmlpath)
 
-	try:
-	    self.desc = self.modules_dict[self.domainname]
-	except:
-	    self.desc = "%s user role" % self.domainname
+        try:
+            self.desc = self.modules_dict[self.domainname]
+        except:
+            self.desc = "%s user role" % self.domainname
 
-	if self.domainname in self.all_users:
-	    self.attributes = sepolicy.info(sepolicy.TYPE,(self.type))[0]["attributes"]
-	    self._user_header()
-	    self._user_attribute()
-	    self._can_sudo()
-	    self._xwindows_login()
-	    # until a new policy build with login_userdomain attribute
-	#self.terminal_login()
-	    self._network()
-	    self._booleans()
-	    self._home_exec()
-	    self._transitions()
-	else:
-	    self._role_header()
-	    self._booleans()
+        if self.domainname in self.all_users:
+            self.attributes = sepolicy.info(sepolicy.TYPE, (self.type))[0]["attributes"]
+            self._user_header()
+            self._user_attribute()
+            self._can_sudo()
+            self._xwindows_login()
+            # until a new policy build with login_userdomain attribute
+        #self.terminal_login()
+            self._network()
+            self._booleans()
+            self._home_exec()
+            self._transitions()
+        else:
+            self._role_header()
+            self._booleans()
 
-	self._port_types()
-	self._writes()
-	self._footer()
+        self._port_types()
+        self._writes()
+        self._footer()
 
     def __gen_man_page_link(self, alias):
-	    path = "%s/%s_selinux.8" % (self.path, alias)
-	    self.fd = open("%s/%s_selinux.8" % (self.path, alias), 'w')
-	    self.fd.write(".so man8/%s_selinux.8" % self.domainname)
-	    self.fd.close()
-	    print path
+        path = "%s/%s_selinux.8" % (self.path, alias)
+        self.fd = open("%s/%s_selinux.8" % (self.path, alias), 'w')
+        self.fd.write(".so man8/%s_selinux.8" % self.domainname)
+        self.fd.close()
+        print path
 
     def __gen_man_page(self):
-	self.anon_list = []
+        self.anon_list = []
 
-	self.attributes = {}
-	self.ptypes = []
-	self._get_ptypes()
+        self.attributes = {}
+        self.ptypes = []
+        self._get_ptypes()
 
-	for domain_type in self.ptypes:
-	    self.attributes[domain_type] = sepolicy.info(sepolicy.TYPE,("%s") % domain_type)[0]["attributes"]
+        for domain_type in self.ptypes:
+            self.attributes[domain_type] = sepolicy.info(sepolicy.TYPE, ("%s") % domain_type)[0]["attributes"]
 
-	self._header()
-	self._entrypoints()
-	self._process_types()
-	self._booleans()
-	self._nsswitch_domain()
-	self._port_types()
-	self._writes()
-	self._file_context()
-	self._public_content()
-	self._footer()
+        self._header()
+        self._entrypoints()
+        self._process_types()
+        self._booleans()
+        self._nsswitch_domain()
+        self._port_types()
+        self._writes()
+        self._file_context()
+        self._public_content()
+        self._footer()
 
     def _get_ptypes(self):
-	for f in self.all_domains:
-		if f.startswith(self.short_name) or f.startswith(self.domainname):
-			self.ptypes.append(f)
+        for f in self.all_domains:
+            if f.startswith(self.short_name) or f.startswith(self.domainname):
+                self.ptypes.append(f)
 
     def _header(self):
-	self.fd.write('.TH  "%(domainname)s_selinux"  "8"  "%(date)s" "%(domainname)s" "SELinux Policy %(domainname)s"'
-		 % {'domainname':self.domainname, 'date': time.strftime("%y-%m-%d")})
-	self.fd.write(r"""
+        self.fd.write('.TH  "%(domainname)s_selinux"  "8"  "%(date)s" "%(domainname)s" "SELinux Policy %(domainname)s"'
+                      % {'domainname': self.domainname, 'date': time.strftime("%y-%m-%d")})
+        self.fd.write(r"""
 .SH "NAME"
 %(domainname)s_selinux \- Security Enhanced Linux Policy for the %(domainname)s processes
 .SH "DESCRIPTION"
@@ -539,24 +558,23 @@
 
 .B ps -eZ | grep %(domainname)s_t
 
-""" % {'domainname':self.domainname})
-
+""" % {'domainname': self.domainname})
 
     def _format_boolean_desc(self, b):
-	    desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
-	    if desc[-1] == ".":
-		    desc = desc[:-1]
-	    return desc
+        desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
+        if desc[-1] == ".":
+            desc = desc[:-1]
+        return desc
 
     def _gen_bool_text(self):
-	booltext = ""
-	for b, enabled in self.domainbools + self.bools:
-		if b.endswith("anon_write") and b not in self.anon_list:
-		    self.anon_list.append(b)
-		else:
-		    if b not in self.booleans_dict:
-			    continue
-		    booltext += """
+        booltext = ""
+        for b, enabled in self.domainbools + self.bools:
+            if b.endswith("anon_write") and b not in self.anon_list:
+                self.anon_list.append(b)
+            else:
+                if b not in self.booleans_dict:
+                    continue
+                booltext += """
 .PP
 If you want to %s, you must turn on the %s boolean. %s by default.
 
@@ -565,48 +583,48 @@
 
 .EE
 """ % (self._format_boolean_desc(b), b, self.enabled_str[enabled], b)
-	return booltext
+        return booltext
 
     def _booleans(self):
-	self.booltext = self._gen_bool_text()
+        self.booltext = self._gen_bool_text()
 
-	if self.booltext != "":
-	    self.fd.write("""
+        if self.booltext != "":
+            self.fd.write("""
 .SH BOOLEANS
 SELinux policy is customizable based on least access required.  %s policy is extremely flexible and has several booleans that allow you to manipulate the policy and run %s with the tightest access possible.
 
 """ % (self.domainname, self.domainname))
 
-	    self.fd.write(self.booltext)
+            self.fd.write(self.booltext)
 
     def _nsswitch_domain(self):
-	nsswitch_types = []
-	nsswitch_booleans = ['authlogin_nsswitch_use_ldap', 'kerberos_enabled']
-	nsswitchbooltext = ""
-	for k in self.attributes.keys():
-		if "nsswitch_domain" in self.attributes[k]:
-			nsswitch_types.append(k)
+        nsswitch_types = []
+        nsswitch_booleans = ['authlogin_nsswitch_use_ldap', 'kerberos_enabled']
+        nsswitchbooltext = ""
+        for k in self.attributes.keys():
+            if "nsswitch_domain" in self.attributes[k]:
+                nsswitch_types.append(k)
 
-	if len(nsswitch_types):
-		self.fd.write("""
+        if len(nsswitch_types):
+            self.fd.write("""
 .SH NSSWITCH DOMAIN
 """)
-		for b in nsswitch_booleans:
-			nsswitchbooltext += """
+            for b in nsswitch_booleans:
+                nsswitchbooltext += """
 .PP
 If you want to %s for the %s, you must turn on the %s boolean.
 
 .EX
 .B setsebool -P %s 1
 .EE
-""" % (self._format_boolean_desc(b),(", ".join(nsswitch_types)), b, b)
+""" % (self._format_boolean_desc(b), (", ".join(nsswitch_types)), b, b)
 
-	self.fd.write(nsswitchbooltext)
+        self.fd.write(nsswitchbooltext)
 
     def _process_types(self):
-	if len(self.ptypes) == 0:
-	    return
-	self.fd.write(r"""
+        if len(self.ptypes) == 0:
+            return
+        self.fd.write(r"""
 .SH PROCESS TYPES
 SELinux defines process types (domains) for each process running on the system
 .PP
@@ -616,27 +634,27 @@
 SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
 .PP
 The following process types are defined for %(domainname)s:
-""" % {'domainname':self.domainname})
-	self.fd.write("""
+""" % {'domainname': self.domainname})
+        self.fd.write("""
 .EX
 .B %s
 .EE""" % ", ".join(self.ptypes))
-	self.fd.write("""
+        self.fd.write("""
 .PP
 Note:
 .B semanage permissive -a %(domainname)s_t
 can be used to make the process type %(domainname)s_t permissive. SELinux does not deny access to permissive process types, but the AVC (SELinux denials) messages are still generated.
-""" % {'domainname':self.domainname})
+""" % {'domainname': self.domainname})
 
     def _port_types(self):
-	self.ports = []
-	for f in self.all_port_types:
+        self.ports = []
+        for f in self.all_port_types:
             if f.startswith(self.short_name) or f.startswith(self.domainname):
-		self.ports.append(f)
+                self.ports.append(f)
 
-	if len(self.ports) == 0:
-	    return
-	self.fd.write("""
+        if len(self.ports) == 0:
+            return
+        self.fd.write("""
 .SH PORT TYPES
 SELinux defines port types to represent TCP and UDP ports.
 .PP
@@ -648,10 +666,10 @@
 Policy governs the access confined processes have to these ports.
 SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
 .PP
-The following port types are defined for %(domainname)s:""" % {'domainname':self.domainname})
+The following port types are defined for %(domainname)s:""" % {'domainname': self.domainname})
 
-	for p in self.ports:
-	    self.fd.write("""
+        for p in self.ports:
+            self.fd.write("""
 
 .EX
 .TP 5
@@ -659,49 +677,49 @@
 .TP 10
 .EE
 """ % p)
-	    once = True
-	    for prot in ( "tcp", "udp" ):
-	       if (p,prot) in self.portrecs:
-		    if once:
-			self.fd.write("""
+            once = True
+            for prot in ("tcp", "udp"):
+                if (p, prot) in self.portrecs:
+                    if once:
+                        self.fd.write("""
 
 Default Defined Ports:""")
-		    once = False
-		    self.fd.write(r"""
+                    once = False
+                    self.fd.write(r"""
 %s %s
-.EE""" % (prot, ",".join(self.portrecs[(p,prot)])))
+.EE""" % (prot, ",".join(self.portrecs[(p, prot)])))
 
     def _file_context(self):
-	flist=[]
-	mpaths=[]
-	for f in self.all_file_types:
-		if f.startswith(self.domainname):
-			flist.append(f)
-			if f in self.fcdict:
-				mpaths = mpaths + self.fcdict[f]["regex"]
-	if len(mpaths) == 0:
-		return
-	mpaths.sort()
-	mdirs={}
-	for mp in mpaths:
-		found = False
-		for md in mdirs:
-			if mp.startswith(md):
-				mdirs[md].append(mp)
-				found = True
-				break
-		if not found:
-			for e in equiv_dirs:
-				if mp.startswith(e) and mp.endswith('(/.*)?'):
-					mdirs[mp[:-6]] = []
-					break
+        flist = []
+        mpaths = []
+        for f in self.all_file_types:
+            if f.startswith(self.domainname):
+                flist.append(f)
+                if f in self.fcdict:
+                    mpaths = mpaths + self.fcdict[f]["regex"]
+        if len(mpaths) == 0:
+            return
+        mpaths.sort()
+        mdirs = {}
+        for mp in mpaths:
+            found = False
+            for md in mdirs:
+                if mp.startswith(md):
+                    mdirs[md].append(mp)
+                    found = True
+                    break
+            if not found:
+                for e in equiv_dirs:
+                    if mp.startswith(e) and mp.endswith('(/.*)?'):
+                        mdirs[mp[:-6]] = []
+                        break
 
-	equiv = []
-	for m in mdirs:
-		if len(mdirs[m]) > 0:
-			equiv.append(m)
+        equiv = []
+        for m in mdirs:
+            if len(mdirs[m]) > 0:
+                equiv.append(m)
 
-	self.fd.write(r"""
+        self.fd.write(r"""
 .SH FILE CONTEXTS
 SELinux requires files to have an extended attribute to define the file type.
 .PP
@@ -710,15 +728,15 @@
 Policy governs the access confined processes have to these files.
 SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
 .PP
-""" % {'domainname':self.domainname})
+""" % {'domainname': self.domainname})
 
-	if len(equiv) > 0:
-		self.fd.write(r"""
+        if len(equiv) > 0:
+            self.fd.write(r"""
 .PP
 .B EQUIVALENCE DIRECTORIES
 """)
-		for e in equiv:
-			self.fd.write(r"""
+            for e in equiv:
+                self.fd.write(r"""
 .PP
 %(domainname)s policy stores data with multiple different file context types under the %(equiv)s directory.  If you would like to store the data in a different directory you can use the semanage command to create an equivalence mapping.  If you wanted to store this data under the /srv dirctory you would execute the following command:
 .PP
@@ -726,9 +744,9 @@
 .br
 .B restorecon -R -v /srv/%(alt)s
 .PP
-""" % {'domainname':self.domainname, 'equiv': e, 'alt': e.split('/')[-1] })
+""" % {'domainname': self.domainname, 'equiv': e, 'alt': e.split('/')[-1] })
 
-	self.fd.write(r"""
+        self.fd.write(r"""
 .PP
 .B STANDARD FILE CONTEXT
 
@@ -740,13 +758,13 @@
 .B restorecon -R -v /srv/my%(domainname)s_content
 
 Note: SELinux often uses regular expressions to specify labels that match multiple files.
-"""  % {'domainname':self.domainname, "type":flist[0] })
+"""  % {'domainname': self.domainname, "type": flist[0] })
 
-	self.fd.write(r"""
+        self.fd.write(r"""
 .I The following file types are defined for %(domainname)s:
-""" % {'domainname':self.domainname})
-	for f in flist:
-		self.fd.write("""
+""" % {'domainname': self.domainname})
+        for f in flist:
+            self.fd.write("""
 
 .EX
 .PP
@@ -756,19 +774,19 @@
 - %s
 """ % ( f, sepolicy.get_description(f)))
 
-		if f in self.fcdict:
-		    plural = ""
-		    if len(self.fcdict[f]["regex"]) > 1:
-			plural = "s"
-			self.fd.write("""
+            if f in self.fcdict:
+                plural = ""
+                if len(self.fcdict[f]["regex"]) > 1:
+                    plural = "s"
+                    self.fd.write("""
 .br
 .TP 5
 Path%s:
 %s""" % (plural, self.fcdict[f]["regex"][0]))
-			for x in self.fcdict[f]["regex"][1:]:
-			    self.fd.write(", %s" % x)
+                    for x in self.fcdict[f]["regex"][1:]:
+                        self.fd.write(", %s" % x)
 
-	self.fd.write("""
+        self.fd.write("""
 
 .PP
 Note: File context can be temporarily modified with the chcon command.  If you want to permanently change the file context you need to use the
@@ -779,19 +797,19 @@
 """)
 
     def _see_also(self):
-	    ret = ""
-	    for d in self.domains:
-		    if d == self.domainname:
-			    continue
-		    if d.startswith(self.short_name):
-			    ret += ", %s_selinux(8)" % d
-		    if d.startswith(self.domainname + "_"):
-			    ret += ", %s_selinux(8)" % d
-	    self.fd.write(ret)
+        ret = ""
+        for d in self.domains:
+            if d == self.domainname:
+                continue
+            if d.startswith(self.short_name):
+                ret += ", %s_selinux(8)" % d
+            if d.startswith(self.domainname + "_"):
+                ret += ", %s_selinux(8)" % d
+        self.fd.write(ret)
 
     def _public_content(self):
-	if len(self.anon_list) > 0:
-	    self.fd.write("""
+        if len(self.anon_list) > 0:
+            self.fd.write("""
 .SH SHARING FILES
 If you want to share files with multiple domains (Apache, FTP, rsync, Samba), you can set a file context of public_content_t and public_content_rw_t.  These context allow any of the above domains to read the content.  If you want a particular domain to write to the public_content_rw_t domain, you must set the appropriate boolean.
 .TP
@@ -811,10 +829,10 @@
 .B restorecon -F -R -v /var/%(domainname)s/incoming
 .br
 .B setsebool -P %(domainname)s_anon_write 1
-"""  % {'domainname':self.domainname})
-	    for b in self.anon_list:
-		desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
-		self.fd.write("""
+"""  % {'domainname': self.domainname})
+            for b in self.anon_list:
+                desc = self.booleans_dict[b][2][0].lower() + self.booleans_dict[b][2][1:]
+                self.fd.write("""
 .PP
 If you want to %s, you must turn on the %s boolean.
 
@@ -824,7 +842,7 @@
 """ % (desc, b, b))
 
     def _footer(self):
-	self.fd.write("""
+        self.fd.write("""
 .SH "COMMANDS"
 .B semanage fcontext
 can also be used to manipulate default file context mappings.
@@ -836,19 +854,19 @@
 can also be used to enable/disable/install/remove policy modules.
 """)
 
-	if len(self.ports) > 0:
-	    self.fd.write("""
+        if len(self.ports) > 0:
+            self.fd.write("""
 .B semanage port
 can also be used to manipulate the port definitions
 """)
 
-	if self.booltext != "":
-	    self.fd.write("""
+        if self.booltext != "":
+            self.fd.write("""
 .B semanage boolean
 can also be used to manipulate the booleans
 """)
 
-	self.fd.write("""
+        self.fd.write("""
 .PP
 .B system-config-selinux
 is a GUI tool available to customize SELinux policy settings.
@@ -861,102 +879,102 @@
 selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8)
 """ % (self.domainname))
 
-	if self.booltext != "":
-	    self.fd.write(", setsebool(8)")
+        if self.booltext != "":
+            self.fd.write(", setsebool(8)")
 
-	self._see_also()
+        self._see_also()
 
     def _valid_write(self, check, attributes):
-	    if check in [ self.type, "domain" ]:
-		    return False
-	    if check.endswith("_t"):
-		    for a in attributes:
-			    if a in self.types[check]:
-				    return False
-	    return True
+        if check in [self.type, "domain"]:
+            return False
+        if check.endswith("_t"):
+            for a in attributes:
+                if a in self.types[check]:
+                    return False
+        return True
 
     def _entrypoints(self):
-	try:
-		entrypoints = map(lambda x: x['target'], sepolicy.search([sepolicy.ALLOW],{'source':self.type,  'permlist':['entrypoint'], 'class':'file'}))
-	except:
-		return
+        try:
+            entrypoints = map(lambda x: x['target'], sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'permlist': ['entrypoint'], 'class': 'file'}))
+        except:
+            return
 
-	self.fd.write ("""
+        self.fd.write ("""
 .SH "ENTRYPOINTS"
 """)
-	if len(entrypoints) > 1:
-		entrypoints_str = "\\fB%s\\fP file types" % ", ".join(entrypoints)
-	else:
-		entrypoints_str = "\\fB%s\\fP file type" % entrypoints[0]
+        if len(entrypoints) > 1:
+            entrypoints_str = "\\fB%s\\fP file types" % ", ".join(entrypoints)
+        else:
+            entrypoints_str = "\\fB%s\\fP file type" % entrypoints[0]
 
-	self.fd.write ("""
+        self.fd.write ("""
 The %s_t SELinux type can be entered via the %s.
 
 The default entrypoint paths for the %s_t domain are the following:
-"""   %	(self.domainname, entrypoints_str, self.domainname))
-	if "bin_t" in entrypoints:
-		entrypoints.remove("bin_t")
-		self.fd.write ("""
+"""   % (self.domainname, entrypoints_str, self.domainname))
+        if "bin_t" in entrypoints:
+            entrypoints.remove("bin_t")
+            self.fd.write ("""
 All executeables with the default executable label, usually stored in /usr/bin and /usr/sbin.""")
 
-	paths=[]
-	for entrypoint in entrypoints:
-		if entrypoint in self.fcdict:
-			paths += self.fcdict[entrypoint]["regex"]
+        paths = []
+        for entrypoint in entrypoints:
+            if entrypoint in self.fcdict:
+                paths += self.fcdict[entrypoint]["regex"]
 
-	self.fd.write("""
+        self.fd.write("""
 %s""" % ", ".join(paths))
 
     def _writes(self):
-	permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type,  'permlist':['open', 'write'], 'class':'file'})
-	if permlist == None or len(permlist) == 0:
-		return
+        permlist = sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'permlist': ['open', 'write'], 'class': 'file'})
+        if permlist == None or len(permlist) == 0:
+            return
 
-	all_writes = []
-	attributes = ["proc_type", "sysctl_type"]
-	for i in permlist:
-		if not i['target'].endswith("_t"):
-			attributes.append(i['target'])
+        all_writes = []
+        attributes = ["proc_type", "sysctl_type"]
+        for i in permlist:
+            if not i['target'].endswith("_t"):
+                attributes.append(i['target'])
 
-	for i in permlist:
-		if self._valid_write(i['target'],attributes):
-			if i['target'] not in all_writes:
-				all_writes.append(i['target'])
+        for i in permlist:
+            if self._valid_write(i['target'], attributes):
+                if i['target'] not in all_writes:
+                    all_writes.append(i['target'])
 
-	if len(all_writes) == 0:
-		return
-	self.fd.write ("""
+        if len(all_writes) == 0:
+            return
+        self.fd.write ("""
 .SH "MANAGED FILES"
 """)
-	self.fd.write ("""
+        self.fd.write ("""
 The SELinux process type %s_t can manage files labeled with the following file types.  The paths listed are the default paths for these file types.  Note the processes UID still need to have DAC permissions.
-"""   %	self.domainname)
+"""   % self.domainname)
 
-	all_writes.sort()
-	if "file_type" in all_writes:
-	    all_writes = [ "file_type" ]
-	for f in all_writes:
-	    self.fd.write("""
+        all_writes.sort()
+        if "file_type" in all_writes:
+            all_writes = ["file_type"]
+        for f in all_writes:
+            self.fd.write("""
 .br
 .B %s
 
 """ % f)
-	    if f in self.fcdict:
-		for path in self.fcdict[f]["regex"]:
-		    self.fd.write("""\t%s
+            if f in self.fcdict:
+                for path in self.fcdict[f]["regex"]:
+                    self.fd.write("""\t%s
 .br
 """ % path)
 
     def _get_users_range(self):
-	    if self.domainname in self.all_users_range:
-		    return self.all_users_range[self.domainname]
-	    return "s0"
+        if self.domainname in self.all_users_range:
+            return self.all_users_range[self.domainname]
+        return "s0"
 
     def _user_header(self):
-	self.fd.write('.TH  "%(type)s_selinux"  "8"  "%(type)s" "mgrepl@redhat.com" "%(type)s SELinux Policy documentation"'
-		      %	{'type':self.domainname})
+        self.fd.write('.TH  "%(type)s_selinux"  "8"  "%(type)s" "mgrepl@redhat.com" "%(type)s SELinux Policy documentation"'
+                      % {'type': self.domainname})
 
-	self.fd.write(r"""
+        self.fd.write(r"""
 .SH "NAME"
 %(user)s_u \- \fB%(desc)s\fP - Security Enhanced Linux Policy
 
@@ -987,39 +1005,39 @@
 
 .B semanage login -m -s %(user)s_u __default__
 
-""" % {'desc': self.desc, 'type':self.type, 'user':self.domainname,'range':self._get_users_range()})
+""" % {'desc': self.desc, 'type': self.type, 'user': self.domainname, 'range': self._get_users_range()})
 
-	if "login_userdomain" in self.attributes and "login_userdomain" in self.all_attributes:
-	    self.fd.write("""
+        if "login_userdomain" in self.attributes and "login_userdomain" in self.all_attributes:
+            self.fd.write("""
 If you want to map the one Linux user (joe) to the SELinux user %(user)s, you would execute:
 
 .B $ semanage login -a -s %(user)s_u joe
 
-"""	%	{'user':self.domainname})
+"""	% {'user': self.domainname})
 
     def _can_sudo(self):
-	sudotype = "%s_sudo_t" % self.domainname
-	self.fd.write("""
+        sudotype = "%s_sudo_t" % self.domainname
+        self.fd.write("""
 .SH SUDO
 """)
-	if sudotype in self.types:
-	    role = self.domainname + "_r"
-	    self.fd.write("""
+        if sudotype in self.types:
+            role = self.domainname + "_r"
+            self.fd.write("""
 The SELinux user %(user)s can execute sudo.
 
 You can set up sudo to allow %(user)s to transition to an administrative domain:
 
 Add one or more of the following record to sudoers using visudo.
 
-""" % { 'user':self.domainname } )
-	    for adminrole in self.role_allows[role]:
-		self.fd.write("""
+""" % { 'user': self.domainname } )
+            for adminrole in self.role_allows[role]:
+                self.fd.write("""
 USERNAME ALL=(ALL) ROLE=%(admin)s_r TYPE=%(admin)s_t COMMAND
 .br
 sudo will run COMMAND as %(user)s_u:%(admin)s_r:%(admin)s_t:LEVEL
-""" % {'admin':adminrole[:-2], 'user':self.domainname } )
+""" % {'admin': adminrole[:-2], 'user': self.domainname } )
 
-		self.fd.write("""
+                self.fd.write("""
 You might also need to add one or more of these new roles to your SELinux user record.
 
 List the SELinux roles your SELinux user can reach by executing:
@@ -1032,105 +1050,105 @@
 
 For more details you can see semanage man page.
 
-""" % {'user':self.domainname, "roles": " ".join([role] + self.role_allows[role]) } )
-	    else:
-		self.fd.write("""
+""" % {'user': self.domainname, "roles": " ".join([role] + self.role_allows[role]) } )
+            else:
+                self.fd.write("""
 The SELinux type %s_t is not allowed to execute sudo.
 """ % self.domainname)
 
     def _user_attribute(self):
-	self.fd.write("""
+        self.fd.write("""
 .SH USER DESCRIPTION
 """)
-	if "unconfined_usertype" in self.attributes:
-	    self.fd.write("""
+        if "unconfined_usertype" in self.attributes:
+            self.fd.write("""
 The SELinux user %s_u is an unconfined user. It means that a mapped Linux user to this SELinux user is supposed to be allow all actions.
 """ % self.domainname)
 
-	if "unpriv_userdomain" in self.attributes:
-	    self.fd.write("""
+        if "unpriv_userdomain" in self.attributes:
+            self.fd.write("""
 The SELinux user %s_u is defined in policy as a unprivileged user. SELinux prevents unprivileged users from doing administration tasks without transitioning to a different role.
 """ % self.domainname)
 
-	if "admindomain" in self.attributes:
-	    self.fd.write("""
+        if "admindomain" in self.attributes:
+            self.fd.write("""
 The SELinux user %s_u is an admin user. It means that a mapped Linux user to this SELinux user is intended for administrative actions. Usually this is assigned to a root Linux user.
 """ % self.domainname)
 
     def _xwindows_login(self):
-	if "x_domain" in self.all_attributes:
-	    self.fd.write("""
+        if "x_domain" in self.all_attributes:
+            self.fd.write("""
 .SH X WINDOWS LOGIN
 """)
-	    if "x_domain" in self.attributes:
-		self.fd.write("""
+            if "x_domain" in self.attributes:
+                self.fd.write("""
 The SELinux user %s_u is able to X Windows login.
 """ % self.domainname)
-	    else:
-		self.fd.write("""
+            else:
+                self.fd.write("""
 The SELinux user %s_u is not able to X Windows login.
 """ % self.domainname)
 
     def _terminal_login(self):
-	if "login_userdomain" in self.all_attributes:
-	    self.fd.write("""
+        if "login_userdomain" in self.all_attributes:
+            self.fd.write("""
 .SH TERMINAL LOGIN
 """)
-	    if "login_userdomain" in self.attributes:
-		self.fd.write("""
+            if "login_userdomain" in self.attributes:
+                self.fd.write("""
 The SELinux user %s_u is able to terminal login.
 """ % self.domainname)
-	    else:
-		self.fd.write("""
+            else:
+                self.fd.write("""
 The SELinux user %s_u is not able to terminal login.
 """ % self.domainname)
 
     def _network(self):
         from sepolicy import network
-	self.fd.write("""
+        self.fd.write("""
 .SH NETWORK
 """)
-	for net in ("tcp", "udp"):
-	    portdict = network.get_network_connect(self.type, net, "name_bind")
-	    if len(portdict) > 0:
-		self.fd.write("""
+        for net in ("tcp", "udp"):
+            portdict = network.get_network_connect(self.type, net, "name_bind")
+            if len(portdict) > 0:
+                self.fd.write("""
 .TP
 The SELinux user %s_u is able to listen on the following %s ports.
 """ % (self.domainname, net))
-		for p in portdict:
-		    for t, ports in portdict[p]:
-			self.fd.write("""
+                for p in portdict:
+                    for t, ports in portdict[p]:
+                        self.fd.write("""
 .B %s
 """ % ",".join(ports))
-	    portdict = network.get_network_connect(self.type, "tcp", "name_connect")
-	    if len(portdict) > 0:
-		self.fd.write("""
+            portdict = network.get_network_connect(self.type, "tcp", "name_connect")
+            if len(portdict) > 0:
+                self.fd.write("""
 .TP
 The SELinux user %s_u is able to connect to the following tcp ports.
 """ % (self.domainname))
-		for p in portdict:
-		    for t, ports in portdict[p]:
-			self.fd.write("""
+                for p in portdict:
+                    for t, ports in portdict[p]:
+                        self.fd.write("""
 .B %s
 """ % ",".join(ports))
 
     def _home_exec(self):
-	permlist = sepolicy.search([sepolicy.ALLOW],{'source':self.type,'target':'user_home_type', 'class':'file', 'permlist':['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']})
-	self.fd.write("""
+        permlist = sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'target': 'user_home_type', 'class': 'file', 'permlist': ['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']})
+        self.fd.write("""
 .SH HOME_EXEC
 """ )
-	if permlist is not None:
-	    self.fd.write("""
+        if permlist is not None:
+            self.fd.write("""
 The SELinux user %s_u is able execute home content files.
 """  % self.domainname)
 
-	else:
-	    self.fd.write("""
+        else:
+            self.fd.write("""
 The SELinux user %s_u is not able execute home content files.
 """  % self.domainname)
 
     def _transitions(self):
-	self.fd.write(r"""
+        self.fd.write(r"""
 .SH TRANSITIONS
 
 Three things can happen when %(type)s attempts to execute a program.
@@ -1153,13 +1171,13 @@
 
 .B $ search -A -s %(type)s -c process -p transition
 
-"""	% {'user':self.domainname, 'type':self.type})
+"""	% {'user': self.domainname, 'type': self.type})
 
     def _role_header(self):
-	self.fd.write('.TH  "%(user)s_selinux"  "8"  "%(user)s" "mgrepl@redhat.com" "%(user)s SELinux Policy documentation"'
-		      %	{'user':self.domainname})
+        self.fd.write('.TH  "%(user)s_selinux"  "8"  "%(user)s" "mgrepl@redhat.com" "%(user)s SELinux Policy documentation"'
+                      % {'user': self.domainname})
 
-	self.fd.write(r"""
+        self.fd.write(r"""
 .SH "NAME"
 %(user)s_r \- \fB%(desc)s\fP - Security Enhanced Linux Policy
 
@@ -1200,17 +1218,17 @@
 
 .B $ semanage user -m -R 'staff_r system_r %(user)s_r' staff_u
 
-""" % {'desc': self.desc, 'user':self.domainname})
-	troles = []
-	for i in self.role_allows:
-	    if self.domainname +"_r" in self.role_allows[i]:
-		troles.append(i)
-	if len(troles) > 0:
-	    plural = ""
-	    if len(troles) > 1:
-		plural = "s"
+""" % {'desc': self.desc, 'user': self.domainname})
+        troles = []
+        for i in self.role_allows:
+            if self.domainname + "_r" in self.role_allows[i]:
+                troles.append(i)
+        if len(troles) > 0:
+            plural = ""
+            if len(troles) > 1:
+                plural = "s"
 
-		self.fd.write("""
+                self.fd.write("""
 
 SELinux policy also controls which roles can transition to a different role.
 You can list these rules using the following command.
diff --git a/policycoreutils/sepolicy/sepolicy/network.py b/policycoreutils/sepolicy/sepolicy/network.py
index 3a75d7c..1ca3158 100755
--- a/policycoreutils/sepolicy/sepolicy/network.py
+++ b/policycoreutils/sepolicy/sepolicy/network.py
@@ -1,5 +1,5 @@
 #! /usr/bin/python -Es
-# Copyright (C) 2012 Red Hat 
+# Copyright (C) 2012 Red Hat
 # see file 'COPYING' for use and warranty information
 #
 # setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,30 +16,31 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #                                        02111-1307  USA
 #
-#  
+#
 import sepolicy
-search=sepolicy.search
-info=sepolicy.info
+search = sepolicy.search
+info = sepolicy.info
+
 
 def get_types(src, tclass, perm):
-    allows=search([sepolicy.ALLOW],{sepolicy.SOURCE:src,sepolicy.CLASS:tclass, sepolicy.PERMS:perm})
-    nlist=[]
+    allows = search([sepolicy.ALLOW], {sepolicy.SOURCE: src, sepolicy.CLASS: tclass, sepolicy.PERMS: perm})
+    nlist = []
     if allows:
         for i in map(lambda y: y[sepolicy.TARGET], filter(lambda x: set(perm).issubset(x[sepolicy.PERMS]), allows)):
             if i not in nlist:
                 nlist.append(i)
     return nlist
-   
+
 
 def get_network_connect(src, protocol, perm):
     portrecs, portrecsbynum = sepolicy.gen_port_dict()
-    d={}
+    d = {}
     tlist = get_types(src, "%s_socket" % protocol, [perm])
     if len(tlist) > 0:
-        d[(src,protocol,perm)] = []
+        d[(src, protocol, perm)] = []
         for i in tlist:
             if i == "ephemeral_port_type":
                 if "unreserved_port_type" in tlist:
@@ -51,18 +52,18 @@
                 if "port_t" in tlist:
                     continue
             if i == "port_t":
-                d[(src,protocol,perm)].append((i, ["all ports with out defined types"]))
+                d[(src, protocol, perm)].append((i, ["all ports with out defined types"]))
             if i == "port_type":
-                d[(src,protocol,perm)].append((i, ["all ports"]))
+                d[(src, protocol, perm)].append((i, ["all ports"]))
             elif i == "unreserved_port_type":
-                d[(src,protocol,perm)].append((i, ["all ports > 1024"]))
+                d[(src, protocol, perm)].append((i, ["all ports > 1024"]))
             elif i == "reserved_port_type":
-                d[(src,protocol,perm)].append((i, ["all ports < 1024"]))
+                d[(src, protocol, perm)].append((i, ["all ports < 1024"]))
             elif i == "rpc_port_type":
-                d[(src,protocol,perm)].append((i, ["all ports > 500 and  < 1024"]))
+                d[(src, protocol, perm)].append((i, ["all ports > 500 and  < 1024"]))
             else:
                 try:
-                    d[(src,protocol,perm)].append((i, portrecs[(i, protocol)]))
+                    d[(src, protocol, perm)].append((i, portrecs[(i, protocol)]))
                 except KeyError:
                     pass
     return d
diff --git a/policycoreutils/sepolicy/sepolicy/sedbus.py b/policycoreutils/sepolicy/sepolicy/sedbus.py
index c6645ef..6055294 100644
--- a/policycoreutils/sepolicy/sepolicy/sedbus.py
+++ b/policycoreutils/sepolicy/sepolicy/sedbus.py
@@ -4,49 +4,51 @@
 import dbus.mainloop.glib
 from slip.dbus import polkit
 
+
 class SELinuxDBus (object):
-    def __init__ (self):
+
+    def __init__(self):
         self.bus = dbus.SystemBus()
         self.dbus_object = self.bus.get_object("org.selinux", "/org/selinux/object")
 
     @polkit.enable_proxy
-    def semanage (self, buf):
-        ret = self.dbus_object.semanage(buf, dbus_interface = "org.selinux")
+    def semanage(self, buf):
+        ret = self.dbus_object.semanage(buf, dbus_interface="org.selinux")
         return ret
 
     @polkit.enable_proxy
-    def restorecon (self, path):
-        ret = self.dbus_object.restorecon(path, dbus_interface = "org.selinux")
+    def restorecon(self, path):
+        ret = self.dbus_object.restorecon(path, dbus_interface="org.selinux")
         return ret
 
     @polkit.enable_proxy
-    def setenforce (self, value):
-        ret = self.dbus_object.setenforce(value, dbus_interface = "org.selinux")
+    def setenforce(self, value):
+        ret = self.dbus_object.setenforce(value, dbus_interface="org.selinux")
         return ret
 
     @polkit.enable_proxy
-    def customized (self):
-        ret = self.dbus_object.customized(dbus_interface = "org.selinux")
+    def customized(self):
+        ret = self.dbus_object.customized(dbus_interface="org.selinux")
         return ret
 
     @polkit.enable_proxy
-    def semodule_list (self):
-        ret = self.dbus_object.semodule_list(dbus_interface = "org.selinux")
+    def semodule_list(self):
+        ret = self.dbus_object.semodule_list(dbus_interface="org.selinux")
         return ret
 
     @polkit.enable_proxy
     def relabel_on_boot(self, value):
-        ret = self.dbus_object.relabel_on_boot(value, dbus_interface = "org.selinux")
+        ret = self.dbus_object.relabel_on_boot(value, dbus_interface="org.selinux")
         return ret
 
     @polkit.enable_proxy
     def change_default_mode(self, value):
-        ret = self.dbus_object.change_default_mode(value, dbus_interface = "org.selinux")
+        ret = self.dbus_object.change_default_mode(value, dbus_interface="org.selinux")
         return ret
 
     @polkit.enable_proxy
     def change_default_policy(self, value):
-        ret = self.dbus_object.change_default_policy(value, dbus_interface = "org.selinux")
+        ret = self.dbus_object.change_default_policy(value, dbus_interface="org.selinux")
         return ret
 
 if __name__ == "__main__":
diff --git a/policycoreutils/sepolicy/sepolicy/transition.py b/policycoreutils/sepolicy/sepolicy/transition.py
index 11834c7..15b0eb1 100755
--- a/policycoreutils/sepolicy/sepolicy/transition.py
+++ b/policycoreutils/sepolicy/sepolicy/transition.py
@@ -1,5 +1,5 @@
 #! /usr/bin/python -Es
-# Copyright (C) 2011 Red Hat 
+# Copyright (C) 2011 Red Hat
 # see file 'COPYING' for use and warranty information
 #
 # setrans is a tool for analyzing process transistions in SELinux policy
@@ -16,31 +16,34 @@
 #
 #    You should have received a copy of the GNU General Public License
 #    along with this program; if not, write to the Free Software
-#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #                                        02111-1307  USA
 #
-#  
+#
 import sepolicy
-search=sepolicy.search
-info=sepolicy.info
-__all__ = [ 'setrans', ]
+search = sepolicy.search
+info = sepolicy.info
+__all__ = ['setrans', ]
+
 
 def _entrypoint(src):
-    trans=search([sepolicy.ALLOW],{sepolicy.SOURCE:src})
+    trans = search([sepolicy.ALLOW], {sepolicy.SOURCE: src})
     return map(lambda y: y[sepolicy.TARGET], filter(lambda x: "entrypoint" in x[sepolicy.PERMS], trans))
-    
+
 
 def _get_trans(src):
-    return search([sepolicy.TRANSITION],{sepolicy.SOURCE:src, sepolicy.CLASS:"process"})
+    return search([sepolicy.TRANSITION], {sepolicy.SOURCE: src, sepolicy.CLASS: "process"})
+
 
 class setrans:
+
     def __init__(self, source, dest=None):
         self.seen = []
         self.sdict = {}
-        self.source=source
-        self.dest=dest
+        self.source = source
+        self.dest = dest
         self._process(self.source)
-            
+
     def _process(self, source):
         if source in self.sdict:
             return self.sdict[source]
@@ -53,10 +56,10 @@
             self.sdict[source]["map"] = trans
         else:
             self.sdict[source]["map"] = map(lambda y: y, filter(lambda x: x["transtype"] == self.dest, trans))
-            self.sdict[source]["child"] = map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest,source] , trans))
+            self.sdict[source]["child"] = map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest, source], trans))
             for s in self.sdict[source]["child"]:
                 self._process(s)
-            
+
     def out(self, name, header=""):
         buf = ""
         if name in self.seen:
@@ -65,7 +68,7 @@
 
         if "map" in self.sdict[name]:
             for t in self.sdict[name]["map"]:
-                cond=sepolicy.get_conditionals(t["source"], t["transtype"],"process",["transition"])
+                cond = sepolicy.get_conditionals(t["source"], t["transtype"], "process", ["transition"])
                 if cond:
                     buf += "%s%s @ %s --> %s %s\n" % (header, t["source"], t["target"], t["transtype"], sepolicy.get_conditionals_format_text(cond))
                 else:
@@ -73,7 +76,7 @@
 
         if "child" in self.sdict[name]:
             for x in self.sdict[name]["child"]:
-                buf+= self.out(x, "%s%s ... " % (header, name))
+                buf += self.out(x, "%s%s ... " % (header, name))
         return buf
 
     def output(self):
diff --git a/policycoreutils/sepolicy/setup.py b/policycoreutils/sepolicy/setup.py
index d8e2d64..e74e68d 100644
--- a/policycoreutils/sepolicy/setup.py
+++ b/policycoreutils/sepolicy/setup.py
@@ -4,9 +4,9 @@
 # Author: Dan Walsh <dwalsh@redhat.com>
 import os
 from distutils.core import setup, Extension
-policy = Extension("sepolicy._policy", 
+policy = Extension("sepolicy._policy",
                    libraries=["apol", "qpol"],
-                   sources=[ "policy.c", "info.c", "search.c"]
-)
+                   sources=["policy.c", "info.c", "search.c"]
+                   )
 
-setup(name = "sepolicy", version="1.1", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", ext_modules=[policy], packages=["sepolicy", "sepolicy.templates", "sepolicy.help"], package_data={'sepolicy':['*.glade'], 'sepolicy.help': ['*.txt', '*.png']})
+setup(name="sepolicy", version="1.1", description="Python SELinux Policy Analyses bindings", author="Daniel Walsh", author_email="dwalsh@redhat.com", ext_modules=[policy], packages=["sepolicy", "sepolicy.templates", "sepolicy.help"], package_data={'sepolicy': ['*.glade'], 'sepolicy.help': ['*.txt', '*.png']})
diff --git a/policycoreutils/sepolicy/test_sepolicy.py b/policycoreutils/sepolicy/test_sepolicy.py
index aef799f..e7bad44 100644
--- a/policycoreutils/sepolicy/test_sepolicy.py
+++ b/policycoreutils/sepolicy/test_sepolicy.py
@@ -1,11 +1,16 @@
-import unittest, os, shutil
+import unittest
+import os
+import shutil
 from tempfile import mkdtemp
 from subprocess import Popen, PIPE
 
+
 class SepolicyTests(unittest.TestCase):
+
     def assertDenied(self, err):
         self.assert_('Permission denied' in err,
                      '"Permission denied" not found in %r' % err)
+
     def assertNotFound(self, err):
         self.assert_('not found' in err,
                      '"not found" not found in %r' % err)
@@ -16,96 +21,96 @@
 
     def assertSuccess(self, status, err):
         self.assert_(status == 0,
-                     '"sepolicy should have succeeded for this test %r' %  err)
+                     '"sepolicy should have succeeded for this test %r' % err)
 
     def test_man_domain(self):
         "Verify sepolicy manpage -d works"
-        p = Popen(['sepolicy', 'manpage', '-d', 'httpd_t'], stdout = PIPE)
+        p = Popen(['sepolicy', 'manpage', '-d', 'httpd_t'], stdout=PIPE)
         out, err = p.communicate()
         print out, err
         self.assertSuccess(p.returncode, err)
 
     def test_man_all(self):
         "Verify sepolicy manpage -a works"
-        p = Popen(['sepolicy', 'manpage', '-a'], stdout = PIPE)
+        p = Popen(['sepolicy', 'manpage', '-a'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_network_l(self):
         "Verify sepolicy network -l works"
-        p = Popen(['sepolicy', 'network', '-l'], stdout = PIPE)
+        p = Popen(['sepolicy', 'network', '-l'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_network_t(self):
         "Verify sepolicy network -t works"
-        p = Popen(['sepolicy', 'network', '-t', 'http_port_t'], stdout = PIPE)
+        p = Popen(['sepolicy', 'network', '-t', 'http_port_t'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_network_p(self):
         "Verify sepolicy network -p works"
-        p = Popen(['sepolicy', 'network', '-p', '80'], stdout = PIPE)
+        p = Popen(['sepolicy', 'network', '-p', '80'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_network_d(self):
         "Verify sepolicy network -d works"
-        p = Popen(['sepolicy', 'network', '-d', 'httpd_t'], stdout = PIPE)
+        p = Popen(['sepolicy', 'network', '-d', 'httpd_t'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_transition_s(self):
         "Verify sepolicy transition -l works"
-        p = Popen(['sepolicy', 'transition', '-s', 'httpd_t'], stdout = PIPE)
+        p = Popen(['sepolicy', 'transition', '-s', 'httpd_t'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_transition_t(self):
         "Verify sepolicy transition -t works"
-        p = Popen(['sepolicy', 'transition', '-s', 'httpd_t', '-t', 'sendmail_t'], stdout = PIPE)
+        p = Popen(['sepolicy', 'transition', '-s', 'httpd_t', '-t', 'sendmail_t'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_booleans_a(self):
         "Verify sepolicy booleans -a works"
-        p = Popen(['sepolicy', 'booleans', '-a'], stdout = PIPE)
+        p = Popen(['sepolicy', 'booleans', '-a'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_booleans_b_alias(self):
         "Verify sepolicy booleans -b works"
-        p = Popen(['sepolicy', 'booleans', '-b', 'allow_ypbind'], stdout = PIPE)
+        p = Popen(['sepolicy', 'booleans', '-b', 'allow_ypbind'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_booleans_b(self):
         "Verify sepolicy booleans -b works"
-        p = Popen(['sepolicy', 'booleans', '-b', 'nis_enabled'], stdout = PIPE)
+        p = Popen(['sepolicy', 'booleans', '-b', 'nis_enabled'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_interface_l(self):
         "Verify sepolicy interface -l works"
-        p = Popen(['sepolicy', 'interface', '-l'], stdout = PIPE)
+        p = Popen(['sepolicy', 'interface', '-l'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_interface_a(self):
         "Verify sepolicy interface -a works"
-        p = Popen(['sepolicy', 'interface', '-a'], stdout = PIPE)
+        p = Popen(['sepolicy', 'interface', '-a'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_interface_p(self):
         "Verify sepolicy interface -u works"
-        p = Popen(['sepolicy', 'interface', '-u'], stdout = PIPE)
+        p = Popen(['sepolicy', 'interface', '-u'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
     def test_interface_ci(self):
         "Verify sepolicy interface -c -i works"
-        p = Popen(['sepolicy', 'interface', '-c', '-i', 'apache_admin'], stdout = PIPE)
+        p = Popen(['sepolicy', 'interface', '-c', '-i', 'apache_admin'], stdout=PIPE)
         out, err = p.communicate()
         self.assertSuccess(p.returncode, err)
 
diff --git a/secilc/Android.mk b/secilc/Android.mk
index ef584e7..3dd9023 100644
--- a/secilc/Android.mk
+++ b/secilc/Android.mk
@@ -5,7 +5,6 @@
 common_cflags := \
 	-Wall -Wshadow -O2 \
 	-pipe -fno-strict-aliasing \
-	-Wno-return-type
 
 ifeq ($(HOST_OS), darwin)
 common_cflags += -DDARWIN
diff --git a/secilc/ChangeLog b/secilc/ChangeLog
index e69de29..eec3454 100644
--- a/secilc/ChangeLog
+++ b/secilc/ChangeLog
@@ -0,0 +1,6 @@
+	* Add documentation and examples for extended avrules, from Steve Lawrence
+	* Added neverallow and bounds checking test policies, from James Carter
+	* Remove uses of -Wno-return-type, from Dan Albert.
+
+2.4 2015-02-02
+	* Initial release.
diff --git a/secilc/docs/cil_access_vector_rules.xml b/secilc/docs/cil_access_vector_rules.xml
index d3ce095..985fc3d 100644
--- a/secilc/docs/cil_access_vector_rules.xml
+++ b/secilc/docs/cil_access_vector_rules.xml
@@ -276,4 +276,176 @@
          </programlisting>
       </sect2>
 
+      <sect2 id="allowx">
+         <title>allowx</title>
+         <para>Specifies the access allowed between a source and target type using extended permissions. Unlike the <literal><link linkend="allow">allow</link></literal> statement, the statements <literal><link linkend="validatetrans">validatetrans</link></literal>, <literal><link linkend="mlsvalidatetrans">mlsvalidatetrans</link></literal>, <literal><link linkend="constrain">constrain</link></literal>, and <literal><link linkend="mlsconstrain">mlsconstrain</link></literal> do not limit accesses granted by <literal><link linkend="allowx">allowx</link></literal>.</para>
+         <para><emphasis role="bold">Rule definition:</emphasis></para>
+         <programlisting><![CDATA[(allowx source_id target_id|self permissionx_id)]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2.25 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal><link linkend="allowx">allowx</link></literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal><link linkend="allowx">allowx</link></literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>source_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously defined source <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal>, or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>target_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously defined target <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal>, or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+                     <para>The <literal>self</literal> keyword may be used instead to signify that source and target are the same.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>permissionx_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single named or anonymous <literal><link linkend="permissionx">permissionx</link></literal>.</para>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+
+         <para><emphasis role="bold">Examples:</emphasis></para>
+         <para>These examples show a selection of possible permutations of <literal><link linkend="allowx">allowx</link></literal> rules:</para>
+         <programlisting><![CDATA[
+(allowx type_1 type_2 (ioctl tcp_socket (range 0x2000 0x20FF)))
+
+(permissionx ioctl_nodebug (ioctl udp_socket (not (range 0x4000 0x4010))))
+(allowx type_3 type_4 ioctl_nodebug)
+]]>
+
+         </programlisting>
+      </sect2>
+
+      <sect2 id="auditallowx">
+         <title>auditallowx</title>
+         <para>Audit the access rights defined if there is a valid <literal><link linkend="allowx">allowx</link></literal> rule. It does NOT allow access, it only audits the event.</para>
+         <para><emphasis role="bold">Rule definition:</emphasis></para>
+         <programlisting><![CDATA[(auditallowx source_id target_id|self permissionx_id)]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2.25 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal><link linkend="auditallowx">auditallowx</link></literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal><link linkend="auditallowx">auditallowx</link></literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>source_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously defined source <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>target_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously defined target <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+                     <para>The <literal>self</literal> keyword may be used instead to signify that source and target are the same.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>permissionx_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single named or anonymous <literal><link linkend="permissionx">permissionx</link></literal>.</para>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+
+         <para><emphasis role="bold">Examples:</emphasis></para>
+         <para>This example will log an audit event whenever the corresponding <literal><link linkend="allowx">allowx</link></literal> rule grants access to the specified extended permissions:</para>
+         <programlisting><![CDATA[
+(allowx type_1 type_2 (ioctl tcp_socket (range 0x2000 0x20FF)))
+
+(auditallowx type_1 type_2 (ioctl tcp_socket (range 0x2005 0x2010)))
+]]>
+         </programlisting>
+      </sect2>
+
+      <sect2 id="dontauditx">
+         <title>dontauditx</title>
+         <para>Do not audit the access rights defined when access denied. This stops excessive log entries for known events.</para>
+         <para>Note that these rules can be omitted by the CIL compiler command line parameter <literal>-D</literal> or <literal>--disable-dontaudit</literal> flags.</para>
+         <para><emphasis role="bold">Rule definition:</emphasis></para>
+         <programlisting><![CDATA[(dontauditx source_id target_id|self permissionx_id)]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2.25 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal><link linkend="dontauditx">dontauditx</link></literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal><link linkend="dontauditx">dontauditx</link></literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>source_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously defined source <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>target_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously defined target <literal><link linkend="type">type</link></literal>, <literal><link linkend="typealias">typealias</link></literal> or <literal><link linkend="typeattribute">typeattribute</link></literal> identifier.</para>
+                     <para>The <literal>self</literal> keyword may be used instead to signify that source and target are the same.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>permissionx_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single named or anonymous <literal><link linkend="permissionx">permissionx</link></literal>.</para>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+
+         <para><emphasis role="bold">Examples:</emphasis></para>
+         <para>This example will not audit the denied access:</para>
+         <programlisting><![CDATA[
+(dontauditx type_1 type_2 (ioctl tcp_socket (range 0x3000 0x30FF)))
+]]>
+         </programlisting>
+      </sect2>
+
    </sect1>
diff --git a/secilc/docs/cil_class_and_permission_statements.xml b/secilc/docs/cil_class_and_permission_statements.xml
index 25929b1..2926d7c 100644
--- a/secilc/docs/cil_class_and_permission_statements.xml
+++ b/secilc/docs/cil_class_and_permission_statements.xml
@@ -490,4 +490,99 @@
          </programlisting>
       </sect2>
 
+      <sect2 id="permissionx">
+         <title>permissionx</title>
+         <para>Defines a named extended permission, which can be used in the <literal><link linkend="allowx">allowx</link></literal>, <literal><link linkend="auditallowx">auditallowx</link></literal>, and <literal><link linkend="dontauditx">dontauditx</link></literal> statements.</para>
+         <para><emphasis role="bold">Statement definition:</emphasis></para>
+         <programlisting><![CDATA[(permissionx permissionx_id (kind class_id (permission ... | expr ...)))]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2.25 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal><link linkend="permissionx">permissionx</link></literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal><link linkend="permissionx">permissionx</link></literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>kind</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A keyword specifying how to interpret the extended permission values. Must be one of:</para>
+                     <para>
+                        <informaltable frame="all">
+                           <tgroup cols="2">
+                              <colspec colwidth=".5 in"/>
+                              <colspec colwidth="*"/>
+                              <thead>
+                              <row>
+                                 <entry align="center">
+                                    <para><emphasis role="bold">kind</emphasis></para>
+                                 </entry>
+                                 <entry align="center">
+                                    <para><emphasis role="bold">description</emphasis></para>
+                                 </entry>
+                              </row>
+                              </thead>
+                              <tbody>
+                              <row>
+                                 <entry>
+                                    <para>ioctl</para>
+                                 </entry>
+                                 <entry>
+                                    <para>Permissions define a whitelist of ioctl values. Permission values must range from <literal>0x0000</literal> to <literal>0xFFFF</literal>, inclusive.</para>
+                                 </entry>
+                              </row>
+                           </tbody></tgroup>
+                        </informaltable>
+                     </para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>class_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously declared <literal><link linkend="class">class</link></literal> identifier.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>permission</literal></para>
+                  </entry>
+                  <entry>
+                     <para>One or more numeric values, specified in decimal, or hexadecimal if prefixed with 0x, or octal if prefixed with 0. Values are interpreted based on the value of <literal>kind</literal>.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>expr</literal></para>
+                  </entry>
+                  <entry>
+                     <para>An expression, with valid operators and syntax:</para>
+                     <simpara><literal>    (range (permission ...) (permission ...))</literal></simpara>
+                     <simpara><literal>    (and (permission ...) (permission ...))</literal></simpara>
+                     <simpara><literal>    (or  (permission ...) (permission ...))</literal></simpara>
+                     <simpara><literal>    (xor (permission ...) (permission ...))</literal></simpara>
+                     <simpara><literal>    (not (permission ...))</literal></simpara>
+                     <simpara><literal>    (all)</literal></simpara>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+         <para><emphasis role="bold">Examples:</emphasis></para>
+         <programlisting><![CDATA[
+(permissionx ioctl_1 (ioctl tcp_socket (0x2000 0x3000 0x4000)))
+(permissionx ioctl_2 (ioctl tcp_socket (range 0x6000 0x60FF)))
+(permissionx ioctl_3 (ioctl tcp_socket (and (range 0x8000 0x90FF) (not (range 0x8100 0x82FF)))))
+]]>
+         </programlisting>
+      </sect2>
+
    </sect1>
diff --git a/secilc/docs/cil_constraint_statements.xml b/secilc/docs/cil_constraint_statements.xml
index 6f5d9c6..8ef1642 100644
--- a/secilc/docs/cil_constraint_statements.xml
+++ b/secilc/docs/cil_constraint_statements.xml
@@ -51,7 +51,7 @@
                      <simpara>and:</simpara>
                         <simpara><literal>  op      : eq neq</literal></simpara>
                         <simpara><literal>  role_op : eq neq dom domby incomp</literal></simpara>
-                        <simpara><literal>  user_id : A single <link linkend="user">user</link> identifier.</literal></simpara>
+                        <simpara><literal>  user_id : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  role_id : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  type_id : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
                   </entry>
@@ -154,7 +154,7 @@
                      <simpara>and:</simpara>
                         <simpara><literal>  op      : eq neq</literal></simpara>
                         <simpara><literal>  role_op : eq neq dom domby incomp</literal></simpara>
-                        <simpara><literal>  user_id : A single <link linkend="user">user</link> identifier.</literal></simpara>
+                        <simpara><literal>  user_id : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  role_id : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  type_id : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
                   </entry>
@@ -236,7 +236,7 @@
                      <simpara>and:</simpara>
                         <simpara><literal>  op          : eq neq</literal></simpara>
                         <simpara><literal>  mls_role_op : eq neq dom domby incomp</literal></simpara>
-                        <simpara><literal>  user_id     : A single <link linkend="user">user</link> identifier.</literal></simpara>
+                        <simpara><literal>  user_id     : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  role_id     : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  type_id     : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
                   </entry>
@@ -332,7 +332,7 @@
                      <simpara>and:</simpara>
                         <simpara><literal>  op          : eq neq</literal></simpara>
                         <simpara><literal>  mls_role_op : eq neq dom domby incomp</literal></simpara>
-                        <simpara><literal>  user_id     : A single <link linkend="user">user</link> identifier.</literal></simpara>
+                        <simpara><literal>  user_id     : A single <link linkend="user">user</link> or <link linkend="userattribute">userattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  role_id     : A single <link linkend="role">role</link> or <link linkend="roleattribute">roleattribute</link> identifier.</literal></simpara>
                         <simpara><literal>  type_id     : A single <link linkend="type">type</link>, <link linkend="typealias">typealias</link> or <link linkend="typeattribute">typeattribute</link> identifier.</literal></simpara>
                   </entry>
diff --git a/secilc/docs/cil_container_statements.xml b/secilc/docs/cil_container_statements.xml
index 6bdd1ab..3e3d2f6 100644
--- a/secilc/docs/cil_container_statements.xml
+++ b/secilc/docs/cil_container_statements.xml
@@ -241,19 +241,30 @@
                      <para><literal><link linkend="allow">allow</link></literal></para>
                   </entry>
                   <entry>
+                     <para><literal><link linkend="allowx">allowx</link></literal></para>
+                  </entry>
+                  <entry>
                      <para><literal><link linkend="auditallow">auditallow</link></literal></para>
                   </entry>
                   <entry>
+                     <para><literal><link linkend="auditallowx">auditallowx</link></literal></para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
                      <para><literal><link linkend="booleanif">booleanif</link></literal></para>
                   </entry>
                   <entry>
                      <para><literal><link linkend="dontaudit">dontaudit</link></literal></para>
                   </entry>
-               </row>
-               <row>
+                  <entry>
+                     <para><literal><link linkend="dontauditx">dontauditx</link></literal></para>
+                  </entry>
                   <entry>
                      <para><literal><link linkend="typepermissive">typepermissive</link></literal></para>
                   </entry>
+               </row>
+               <row>
                   <entry>
                      <para><literal><link linkend="rangetransition">rangetransition</link></literal></para>
                   </entry>
@@ -263,11 +274,11 @@
                   <entry>
                      <para><literal><link linkend="roleallow">roleallow</link></literal></para>
                   </entry>
-               </row>
-               <row>
                   <entry>
                      <para><literal><link linkend="roleattribute">roleattribute</link></literal></para>
                   </entry>
+               </row>
+               <row>
                   <entry>
                      <para><literal><link linkend="roletransition">roletransition</link></literal></para>
                   </entry>
@@ -277,11 +288,11 @@
                   <entry>
                      <para><literal><link linkend="typealias">typealias</link></literal></para>
                   </entry>
-               </row>
-               <row>
                   <entry>
                      <para><literal><link linkend="typeattribute">typeattribute</link></literal></para>
                   </entry>
+              </row>
+              <row>
                   <entry>
                      <para><literal><link linkend="typechange">typechange</link></literal></para>
                   </entry>
diff --git a/secilc/docs/cil_user_statements.xml b/secilc/docs/cil_user_statements.xml
index 9fa1a51..38a7d6e 100644
--- a/secilc/docs/cil_user_statements.xml
+++ b/secilc/docs/cil_user_statements.xml
@@ -66,7 +66,7 @@
                      <para><literal>user_id</literal></para>
                   </entry>
                   <entry>
-                     <para>A previously declared SELinux <literal><link linkend="user">user</link></literal> identifier.</para>
+                     <para>A previously declared SELinux <literal><link linkend="user">user</link></literal> or <literal><link linkend="userattribute">userattribute</link></literal> identifier.</para>
                   </entry>
                </row>
                <row>
@@ -91,6 +91,114 @@
          </programlisting>
       </sect2>
 
+      <sect2 id="userattribute">
+         <title>userattribute</title>
+         <para>Declares a user attribute identifier in the current namespace. The identifier may have zero or more <literal><link linkend="user">user</link></literal> and <literal><link linkend="userattribute">userattribute</link></literal> identifiers associated to it via the <literal><link linkend="userattributeset">userattributeset</link></literal> statement.</para>
+         <para><emphasis role="bold">Statement definition:</emphasis></para>
+         <programlisting><![CDATA[(userattribute userattribute_id)]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal>userattribute</literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal>userattribute</literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>userattribute_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal>userattribute</literal> identifier.</para>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+
+         <para><emphasis role="bold">Example:</emphasis></para>
+         <para>This example will declare a user attribute <literal>users.user_holder</literal> that will have an empty set:</para>
+         <programlisting><![CDATA[
+(block users
+    (userattribute user_holder)
+)]]>
+         </programlisting>
+      </sect2>
+
+      <sect2 id="userattributeset">
+         <title>userattributeset</title>
+         <para>Allows the association of one or more previously declared <literal><link linkend="user">user</link></literal> or <literal><link linkend="userattribute">userattribute</link></literal> identifiers to a <literal><link linkend="userattribute">userattribute</link></literal> identifier. Expressions may be used to refine the associations as shown in the examples.</para>
+         <para><emphasis role="bold">Statement definition:</emphasis></para>
+         <programlisting><![CDATA[(userattributeset userattribute_id (user_id ... | expr ...))]]></programlisting>
+         <para><emphasis role="bold">Where:</emphasis></para>
+         <informaltable frame="all">
+            <tgroup cols="2">
+            <colspec colwidth="2 *"/>
+            <colspec colwidth="6 *"/>
+               <tbody>
+               <row>
+                  <entry>
+                     <para><literal>userattributeset</literal></para>
+                  </entry>
+                  <entry>
+                     <para>The <literal>userattributeset</literal> keyword.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>userattribute_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>A single previously declared <literal><link linkend="roleattribute">userattribute</link></literal> identifier.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>user_id</literal></para>
+                  </entry>
+                  <entry>
+                     <para>Zero or more previously declared <literal><link linkend="role">user</link></literal> or <literal><link linkend="userattribute">userattribute</link></literal> identifiers.</para>
+                     <para>Note that there must be at least one <literal>user_id</literal> or <literal>expr</literal> parameter declared.</para>
+                  </entry>
+               </row>
+               <row>
+                  <entry>
+                     <para><literal>expr</literal></para>
+                  </entry>
+                  <entry>
+                     <para>Zero or more <literal>expr</literal>'s, the valid operators and syntax are:</para>
+                     <simpara><literal>    (and (user_id ...) (user_id ...))</literal></simpara>
+                     <simpara><literal>    (or  (user_id ...) (user_id ...))</literal></simpara>
+                     <simpara><literal>    (xor (user_id ...) (user_id ...))</literal></simpara>
+                     <simpara><literal>    (not (user_id ...))</literal></simpara>
+                     <simpara><literal>    (all)</literal></simpara>
+                  </entry>
+               </row>
+            </tbody></tgroup>
+         </informaltable>
+
+         <para><emphasis role="bold">Example:</emphasis></para>
+         <para>This example will declare three users and two user attributes, then associate all the users to them as shown:</para>
+         <programlisting><![CDATA[
+(block users
+    (user user_1)
+    (user user_2)
+    (user user_3)
+
+    (userattribute user_holder)
+    (userattributeset user_holder (user_1 user_2 user_3))
+
+    (userattribute user_holder_all)
+    (userattributeset user_holder_all (all))
+)]]>
+         </programlisting>
+      </sect2>
+
       <sect2 id="userlevel">
          <title>userlevel</title>
          <para>Associates a previously declared <literal><link linkend="user">user</link></literal> identifier with a previously declared <literal><link linkend="level">level</link></literal> identifier. The <literal><link linkend="level">level</link></literal> may be named or anonymous.</para>
diff --git a/secilc/test/bounds.cil b/secilc/test/bounds.cil
new file mode 100644
index 0000000..e72560e
--- /dev/null
+++ b/secilc/test/bounds.cil
@@ -0,0 +1,241 @@
+(class CLASS (PERM))
+(classorder (CLASS))
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(type TYPE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(allow TYPE self (CLASS (PERM)))
+(roletype ROLE TYPE)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))
+
+(class c1 (p1a p1b p1c))
+(class c2 (p2a p2b p2c))
+(class c3 (p3a p3b p3c))
+
+(classorder (CLASS c1 c2 c3))
+
+(classpermission cp1)
+(classpermissionset cp1 (c1 (p1a p1b)))
+(classpermissionset cp1 (c2 (p2a)))
+
+(classmap cm1 (mp1))
+(classmapping cm1 mp1
+	      (c1 (p1a)))
+
+(boolean b_b1 false)
+(boolean b_b2 false)
+(boolean b_b3 false)
+
+
+(type b_ta)
+(type b_tb)
+(type b_tc)
+(type b_td)
+
+
+;; All of these rules should pass the bounds check
+(type b_t1)
+(type b_t1_c)
+(typebounds b_t1 b_t1_c)
+
+(allow b_t1 self (CLASS (PERM)))
+(allow b_t1_c self (CLASS (PERM)))
+(allow b_t1 b_ta (CLASS (PERM)))
+(allow b_t1_c b_ta (CLASS (PERM)))
+(allow b_ta b_t1 (CLASS (PERM)))
+(allow b_ta b_t1_c (CLASS (PERM)))
+
+(booleanif b_b1
+  (false
+    (allow b_t1 b_tb (CLASS (PERM)))
+    (allow b_t1_c b_tb (CLASS (PERM)))
+    (allow b_tb b_t1 (CLASS (PERM)))
+    (allow b_tb b_t1_c (CLASS (PERM)))))
+
+(allow b_t1 b_tc (CLASS (PERM)))
+(allow b_tc b_t1 (CLASS (PERM)))
+(booleanif b_b2
+  (false
+    (allow b_t1_c b_tc (CLASS (PERM)))
+    (allow b_tc b_t1_c (CLASS (PERM)))))
+
+(allow b_t1_c b_td (CLASS (PERM)))
+(allow b_td b_t1_c (CLASS (PERM)))
+(booleanif b_b3
+  (true
+    (allow b_t1 b_td (CLASS (PERM)))
+    (allow b_td b_t1 (CLASS (PERM))))
+  (false
+    (allow b_t1 b_td (CLASS (PERM)))
+    (allow b_td b_t1 (CLASS (PERM)))))
+
+
+;; All of these rules should pass the bounds check
+(type b_t2)
+(type b_t2_c)
+(typebounds b_t2 b_t2_c)
+(typeattribute b_a2)
+(typeattribute b_a2_c)
+(typeattributeset b_a2 b_t2)
+(typeattributeset b_a2_c b_t2_c)
+
+(allow b_a2 self (CLASS (PERM)))
+(allow b_a2_c self (CLASS (PERM)))
+(allow b_a2 b_ta (CLASS (PERM)))
+(allow b_a2_c b_ta (CLASS (PERM)))
+(allow b_ta b_a2 (CLASS (PERM)))
+(allow b_ta b_a2_c (CLASS (PERM)))
+
+(booleanif b_b1
+  (false
+    (allow b_a2 b_tb (CLASS (PERM)))
+    (allow b_a2_c b_tb (CLASS (PERM)))
+    (allow b_tb b_a2 (CLASS (PERM)))
+    (allow b_tb b_a2_c (CLASS (PERM)))))
+
+(allow b_a2 b_tc (CLASS (PERM)))
+(allow b_tc b_a2 (CLASS (PERM)))
+(booleanif b_b2
+  (false
+    (allow b_a2_c b_tc (CLASS (PERM)))
+    (allow b_tc b_a2_c (CLASS (PERM)))))
+
+(allow b_a2_c b_td (CLASS (PERM)))
+(allow b_td b_a2_c (CLASS (PERM)))
+(booleanif b_b3
+  (true
+    (allow b_a2 b_td (CLASS (PERM)))
+    (allow b_td b_a2 (CLASS (PERM))))
+  (false
+    (allow b_a2 b_td (CLASS (PERM)))
+    (allow b_td b_a2 (CLASS (PERM)))))
+
+
+;; All of these rules should fail the bounds check
+(type b_t3)
+(type b_t3_c)
+(typebounds b_t3 b_t3_c)
+
+(allow b_t3 self (CLASS (PERM)))
+(allow b_t3_c self (c1 (p1a)))
+(allow b_t3 b_ta (CLASS (PERM)))
+(allow b_t3_c b_ta (c1 (p1a)))
+(allow b_ta b_t3 (CLASS (PERM)))
+(allow b_ta b_t3_c (c1 (p1a)))
+
+(booleanif b_b1
+  (false
+    (allow b_t3_c b_tb (c1 (p1a)))
+    (allow b_tb b_t3_c (c1 (p1a)))))
+
+(booleanif b_b2
+  (true
+    (allow b_t3_c b_tc (c1 (p1a)))
+    (allow b_tc b_t3_c (c1 (p1a))))
+  (false
+    (allow b_t3 b_tc (c1 (p1a)))
+    (allow b_tc b_t3 (c1 (p1a)))))
+
+(allow b_t3_c b_td (c1 (p1a)))
+(allow b_td b_t3_c (c1 (p1a)))
+(booleanif b_b3
+  (false
+    (allow b_t3 b_td (c1 (p1a)))
+    (allow b_td b_t3 (c1 (p1a)))))
+
+
+;; All of these rules should fail the bounds check
+(type b_t4)
+(type b_t4_c)
+(typebounds b_t4 b_t4_c)
+(typeattribute b_a4)
+(typeattribute b_a4_c)
+(typeattributeset b_a4 b_t4)
+(typeattributeset b_a4_c b_t4_c)
+
+(allow b_a4 self (CLASS (PERM)))
+(allow b_a4_c self (c1 (p1a)))
+(allow b_a4 b_ta (CLASS (PERM)))
+(allow b_a4_c b_ta (c1 (p1a)))
+(allow b_ta b_a4 (CLASS (PERM)))
+(allow b_ta b_a4_c (c1 (p1a)))
+
+(booleanif b_b1
+  (false
+    (allow b_a4_c b_tb (c1 (p1a)))
+    (allow b_tb b_a4_c (c1 (p1a)))))
+
+(booleanif b_b2
+  (true
+    (allow b_a4_c b_tc (c1 (p1a)))
+    (allow b_tc b_a4_c (c1 (p1a))))
+  (false
+    (allow b_a4 b_tc (c1 (p1a)))
+    (allow b_tc b_a4 (c1 (p1a)))))
+
+(allow b_a4_c b_td (c1 (p1a)))
+(allow b_td b_a4_c (c1 (p1a)))
+(booleanif b_b3
+  (false
+    (allow b_a4 b_td (c1 (p1a)))
+    (allow b_td b_a4 (c1 (p1a)))))
+
+
+;; Marked rules should fail, all others should pass
+(type b_t5)
+(type b_t5_c)
+(typebounds b_t5 b_t5_c)
+
+(allow b_t5 b_ta cp1)
+(allow b_t5_c b_ta (c1 (p1a)))
+(allow b_t5_c b_ta (c2 (p2a)))
+(allow b_t5_c b_ta (c2 (p2b))) ;; Fail
+(allow b_t5_c b_ta (c3 (p3a))) ;; Fail
+
+(allow b_t5 b_tb (c1 (p1a p1b)))
+(allow b_t5 b_tb (c2 (p2a)))
+(allow b_t5_c b_tb cp1)
+
+(allow b_t5 b_tc (cm1 (mp1)))
+(allow b_t5_c b_tc (c1 (p1a)))
+(allow b_t5_c b_tc (c1 (p1b))) ;; Fail
+(allow b_t5_c b_tc (c2 (p2a))) ;; Fail
+
+(allow b_t5 b_tc (c1 (p1a)))
+(allow b_t5_c b_tc (cm1 (mp1)))
+
+
+;; Marked rules should fail, all others should pass
+(type b_t6a)
+(type b_t6a_c)
+(type b_t6b)
+(type b_t6b_c)
+(typebounds b_t6a b_t6a_c)
+(typebounds b_t6b b_t6b_c)
+
+(allow b_t6a b_t6b (CLASS (PERM)))
+(allow b_t6a_c b_t6b_c (CLASS (PERM)))
+
+;; Needs: (allow b_t6a b_t6b (c1 (p1a)))
+(allow b_t6a_c b_t6b (c1 (p1a))) ;; Fail
+(allow b_t6a_c b_t6b_c (c1 (p1a))) ;; Fail
+
+;; Needs: (allow b_t6a b_t6b (c2 (p2a)))
+(allow b_t6a b_t6b_c (c2 (p2a))) ;; Fail
+(allow b_t6a_c b_t6b (c2 (p2a))) ;; Fail
+(allow b_t6a_c b_t6b_c (c2 (p2a)))
+
+;; Needs: (allow b_t6a b_t6b (c3 (p3c)))
+(allow b_t6a b_t6b (c3 (p3a p3b)))
+(allow b_t6a b_t6b_c (c3 (p3b p3c))) ;; Fail
+(allow b_t6a_c b_t6b (c3 (p3a p3c))) ;; Fail
+(allow b_t6a_c b_t6b_c (c3 (p3a p3b p3c))) ;; Fail
diff --git a/secilc/test/neverallow.cil b/secilc/test/neverallow.cil
new file mode 100644
index 0000000..6351558
--- /dev/null
+++ b/secilc/test/neverallow.cil
@@ -0,0 +1,79 @@
+(class CLASS (PERM))
+(classorder (CLASS))
+(sid SID)
+(sidorder (SID))
+(user USER)
+(role ROLE)
+(type TYPE)
+(category CAT)
+(categoryorder (CAT))
+(sensitivity SENS)
+(sensitivityorder (SENS))
+(sensitivitycategory SENS (CAT))
+(allow TYPE self (CLASS (PERM)))
+(roletype ROLE TYPE)
+(userrole USER ROLE)
+(userlevel USER (SENS))
+(userrange USER ((SENS)(SENS (CAT))))
+(sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))
+
+(class c1 (p1a p1b p1c))
+(class c2 (p2a p2b p2c))
+(class c3 (p3a p3b p3c))
+
+(classorder (CLASS c1 c2 c3))
+
+(classpermission cp1)
+(classpermissionset cp1 (c1 (p1a p1b)))
+(classpermissionset cp1 (c2 (p2a)))
+
+(classmap cm1 (mp1))
+(classmapping cm1 mp1
+	      (c1 (p1a)))
+
+(type t1)
+(type t2)
+(type t3)
+(type t4)
+(type t5)
+(type t6)
+(type t7)
+
+(typeattribute a1)
+(typeattribute a2)
+(typeattribute a3)
+(typeattribute a4)
+(typeattribute a5)
+(typeattribute a6)
+
+(typeattributeset a1 (t1 t2 t3 t4 t5))
+(typeattributeset a2 (t1 t2))
+(typeattributeset a3 (t3 t4))
+(typeattributeset a4 (t2 t3))
+(typeattributeset a5 (t5 t6))
+(typeattributeset a6 (t6 t7))
+
+(neverallow t1 t2 (c1 (p1a p1b)))
+(allow t1 t2 (c1 (p1a)))
+
+(neverallow t3 t4 (cm1 (mp1)))
+(allow t3 t4 (c1 (p1a)))
+
+(neverallow t5 t6 cp1)
+(allow t5 t6 (c1 (p1b)))
+(allow t5 t6 (c2 (p2a)))
+
+(neverallow a1 self (CLASS (PERM)))
+(allow t1 t1 (CLASS (PERM)))
+(allow t2 self (CLASS (PERM)))
+(allow a3 self (CLASS (PERM)))
+(allow a2 a4 (CLASS (PERM)))
+
+(neverallow a5 a6 (CLASS (PERM)))
+(allow t5 t7 (CLASS (PERM)))
+(allow t6 self (CLASS (PERM)))
+
+;; Should not call these violations
+(allow a1 self (c1 (p1a)))
+(allow a2 a3 (CLASS (PERM)))
+(allow t5 t6 (c2 (p2b)))
diff --git a/secilc/test/policy.cil b/secilc/test/policy.cil
index 25c8545..69103d1 100644
--- a/secilc/test/policy.cil
+++ b/secilc/test/policy.cil
@@ -91,6 +91,9 @@
 	;;(allow console_t console_device_t file_rw)
 	(allow console_t console_device_t (files (read)))
 
+	(permissionx ioctl_test (ioctl files (and (range 0x1600 0x19FF) (not (range 0x1750 0x175F)))))
+	(allowx console_t console_device_t ioctl_test)
+
 	(boolean secure_mode false)
 	(boolean console_login true)
 	
@@ -114,9 +117,6 @@
 	(typealias sbin_t)
 	(typealiasactual sbin_t bin_t)
 	(typepermissive device_t) 
-	(typebounds device_t bin_t)
-	;;(typebounds bin_t kernel_t)    ;; This statement and the next can be used
-	;;(typebounds kernel_t device_t) ;; to verify that circular bounds can be found 
 	(typemember device_t bin_t file exec_t)
 	(typetransition device_t console_t files console_device_t)
 
@@ -124,7 +124,9 @@
 	(roleattribute foo_role)
 	(roleattribute bar_role)
 	(roleattribute baz_role)
+	(roleattribute foo_role_a)
 	(roleattributeset exec_role (or user_r system_r))
+	(roleattributeset foo_role_a (baz_r user_r system_r))
 	(roleattributeset foo_role (and exec_role system_r))
 	(roleattributeset bar_role (xor exec_role foo_role))
 	(roleattributeset baz_role (not user_r))
@@ -194,6 +196,7 @@
 
 	(role system_r)
 	(role user_r)
+	(role baz_r)
 
 	(roletype system_r bin_t)
 	(roletype system_r kernel_t)
@@ -203,17 +206,32 @@
 	(roletype exec_role bin_t)
 	(roletype exec_role exec_type)
 	(roleallow system_r user_r)
-	(rolebounds system_r user_r)
 	(roletransition system_r bin_t file user_r)
 
 	(userrole foo_u foo_role)
 	(userlevel foo_u low)
+
+	(userattribute ua1)
+	(userattribute ua2)
+	(userattribute ua3)
+	(userattribute ua4)
+	(userattributeset ua1 (user_u system_u))
+	(userattributeset ua2 (foo_u system_u))
+	(userattributeset ua3 (and ua1 ua2))
+	(user u5)
+	(user u6)
+	(userlevel u5 low)
+	(userlevel u6 low)
+	(userrange u5 low_high)
+	(userrange u6 low_high)
+	(userattributeset ua4 (u5 u6))
+	(userrole ua4 foo_role_a)
+
 	(userrange foo_u low_high)
 
 	(userrole system_u system_r)
 	(userlevel system_u low)
 	(userrange system_u low_high)
-	(userbounds system_u user_u)
 
 	(userrole user_u user_r)
 	(userlevel user_u (s0 (range c0 c2)))
@@ -255,7 +273,7 @@
 	(constrain (files (read)) (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
 	(constrain char_w (not (or (and (eq t1 exec_t) (eq t2 bin_t)) (eq r1 r2))))
 
-	(constrain (file (read)) (or (and (eq t1 exec_t) (neq t2 bin_t) ) (eq u1 u2) ) )
+	(constrain (file (read)) (or (and (eq t1 exec_t) (neq t2 bin_t) ) (eq u1 ua4) ) )
 	(constrain (file (open)) (dom r1 r2))
 	(constrain (file (open)) (domby r1 r2))
 	(constrain (file (open)) (incomp r1 r2))
@@ -286,6 +304,7 @@
 
 (macro all ((type x))
 	(allow x bin_t (policy.file (execute)))
+	(allowx x bin_t (ioctl policy.file (range 0x1000 0x11FF)))
 )
 (call all (bin_t))
 
diff --git a/sepolgen/ChangeLog b/sepolgen/ChangeLog
index d2756bc..3d59852 100644
--- a/sepolgen/ChangeLog
+++ b/sepolgen/ChangeLog
@@ -1,3 +1,8 @@
+	* Reset line numbers when parsing files, from Nicolas Iooss.
+	* Convert cmp functions to key functions, from Robert Kuska.
+	* Decode output from Popen in Python3, from Robert Kuska.
+	* Comment constraint rules in output, from Miroslav Grepl via Petr Lautrbach.
+	* Add support for python3, from Robert Kuska.
 	* Add device tree ocontext nodes to Xen policy, from Daniel De Graaf.
 
 1.2.2 2015-02-02
diff --git a/sepolgen/src/sepolgen/access.py b/sepolgen/src/sepolgen/access.py
index cf13210..1f89ecd 100644
--- a/sepolgen/src/sepolgen/access.py
+++ b/sepolgen/src/sepolgen/access.py
@@ -31,7 +31,9 @@
 in a variety of ways, but they are the fundamental representation of access.
 """
 
-import refpolicy
+from . import refpolicy
+from . import util
+
 from selinux import audit2why
 
 def is_idparam(id):
@@ -51,7 +53,7 @@
     else:
         return False
 
-class AccessVector:
+class AccessVector(util.Comparison):
     """
     An access vector is the basic unit of access in SELinux.
 
@@ -88,6 +90,9 @@
             self.audit_msgs = []
             self.type = audit2why.TERULE
             self.data = []
+        # when implementing __eq__ also __hash__ is needed on py2
+        # if object is muttable __hash__ should be None
+        self.__hash__ = None
 
         # The direction of the information flow represented by this
         # access vector - used for matching
@@ -133,23 +138,19 @@
         return "allow %s %s:%s %s;" % (self.src_type, self.tgt_type,
                                         self.obj_class, self.perms.to_space_str())
 
-    def __cmp__(self, other):
-        if self.src_type != other.src_type:
-            return cmp(self.src_type, other.src_type)
-        if self.tgt_type != other.tgt_type:
-            return cmp(self.tgt_type, other.tgt_type)
-        if self.obj_class != self.obj_class:
-            return cmp(self.obj_class, other.obj_class)
-        if len(self.perms) != len(other.perms):
-            return cmp(len(self.perms), len(other.perms))
-        x = list(self.perms)
-        x.sort()
-        y = list(other.perms)
-        y.sort()
-        for pa, pb in zip(x, y):
-            if pa != pb:
-                return cmp(pa, pb)
-        return 0
+    def _compare(self, other, method):
+        try:
+            x = list(self.perms)
+            a = (self.src_type, self.tgt_type, self.obj_class, x)
+            y = list(other.perms)
+            x.sort()
+            y.sort()
+            b = (other.src_type, other.tgt_type, other.obj_class, y)
+            return method(a, b)
+        except (AttributeError, TypeError):
+            # trying to compare to foreign type
+            return NotImplemented
+
 
 def avrule_to_access_vectors(avrule):
     """Convert an avrule into a list of access vectors.
@@ -262,7 +263,7 @@
         tgt = self.src.setdefault(src_type, { })
         cls = tgt.setdefault(tgt_type, { })
         
-        if cls.has_key((obj_class, avc_type)):
+        if (obj_class, avc_type) in cls:
             access = cls[obj_class, avc_type]
         else:
             access = AccessVector()
@@ -293,7 +294,7 @@
 def avs_extract_obj_perms(avs):
     perms = { }
     for av in avs:
-        if perms.has_key(av.obj_class):
+        if av.obj_class in perms:
             s = perms[av.obj_class]
         else:
             s = refpolicy.IdSet()
@@ -321,7 +322,7 @@
         return len(self.role_types.keys())
 
     def add(self, role, type):
-        if self.role_types.has_key(role):
+        if role in self.role_types:
             role_type = self.role_types[role]
         else:
             role_type = refpolicy.RoleType()
diff --git a/sepolgen/src/sepolgen/audit.py b/sepolgen/src/sepolgen/audit.py
index 56919be..724d3ea 100644
--- a/sepolgen/src/sepolgen/audit.py
+++ b/sepolgen/src/sepolgen/audit.py
@@ -17,11 +17,12 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
 
-import refpolicy
-import access
 import re
 import sys
 
+from . import refpolicy
+from . import access
+from . import util
 # Convenience functions
 
 def get_audit_boot_msgs():
@@ -42,6 +43,8 @@
     boottime = time.strftime("%X", s)
     output = subprocess.Popen(["/sbin/ausearch", "-m", "AVC,USER_AVC,MAC_POLICY_LOAD,DAEMON_START,SELINUX_ERR", "-ts", bootdate, boottime],
                               stdout=subprocess.PIPE).communicate()[0]
+    if util.PY3:
+        output = util.decode_input(output)
     return output
 
 def get_audit_msgs():
@@ -55,6 +58,8 @@
     import subprocess
     output = subprocess.Popen(["/sbin/ausearch", "-m", "AVC,USER_AVC,MAC_POLICY_LOAD,DAEMON_START,SELINUX_ERR"],
                               stdout=subprocess.PIPE).communicate()[0]
+    if util.PY3:
+        output = util.decode_input(output)
     return output
 
 def get_dmesg_msgs():
@@ -66,6 +71,8 @@
     import subprocess
     output = subprocess.Popen(["/bin/dmesg"],
                               stdout=subprocess.PIPE).communicate()[0]
+    if util.PY3:
+        output = util.decode_input(output)
     return output
 
 # Classes representing audit messages
@@ -430,7 +437,7 @@
 
         # Group by audit header
         if msg.header != "":
-            if self.by_header.has_key(msg.header):
+            if msg.header in self.by_header:
                 self.by_header[msg.header].append(msg)
             else:
                 self.by_header[msg.header] = [msg]
diff --git a/sepolgen/src/sepolgen/classperms.py b/sepolgen/src/sepolgen/classperms.py
index c925dee..f4fd899 100644
--- a/sepolgen/src/sepolgen/classperms.py
+++ b/sepolgen/src/sepolgen/classperms.py
@@ -49,10 +49,10 @@
     return t
 
 def t_error(t):
-    print "Illegal character '%s'" % t.value[0]
+    print("Illegal character '%s'" % t.value[0])
     t.skip(1)
 
-import lex
+from . import lex
 lex.lex()
 
 def p_statements(p):
@@ -90,9 +90,9 @@
         p[0] = [p[1]] + p[2]
 
 def p_error(p):
-    print "Syntax error on line %d %s [type=%s]" % (p.lineno, p.value, p.type)
+    print("Syntax error on line %d %s [type=%s]" % (p.lineno, p.value, p.type))
     
-import yacc
+from . import yacc
 yacc.yacc()
 
 
@@ -112,5 +112,5 @@
 define(`all_security_perms',`{ compute_av compute_create compute_member check_context load_policy compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot }')
 """
 result = yacc.parse(txt)
-print result
+print(result)
     
diff --git a/sepolgen/src/sepolgen/defaults.py b/sepolgen/src/sepolgen/defaults.py
index 218bc7c..9591063 100644
--- a/sepolgen/src/sepolgen/defaults.py
+++ b/sepolgen/src/sepolgen/defaults.py
@@ -36,14 +36,14 @@
             if ignore.match(line): continue
             mo = consider.match(line)
             if not mo:
-                raise ValueError, "%s:%d: line is not in key = value format" % (pathname, lineno+1)
+                raise ValueError("%s:%d: line is not in key = value format" % (pathname, lineno+1))
             self.config[mo.group(1)] = mo.group(2)
 
     # We're only exporting one useful function, so why not be a function
     def __call__(self, testfilename, pathset="SELINUX_DEVEL_PATH"):
         paths = self.config.get(pathset, None)
         if paths is None:
-            raise ValueError, "%s was not in %s" % (pathset, self.config_pathname)
+            raise ValueError("%s was not in %s" % (pathset, self.config_pathname))
         paths = paths.split(":")
         for p in paths:
             target = os.path.join(p, testfilename)
diff --git a/sepolgen/src/sepolgen/interfaces.py b/sepolgen/src/sepolgen/interfaces.py
index 88a6dc3..0b688bf 100644
--- a/sepolgen/src/sepolgen/interfaces.py
+++ b/sepolgen/src/sepolgen/interfaces.py
@@ -21,15 +21,15 @@
 Classes for representing and manipulating interfaces.
 """
 
-import access
-import refpolicy
-import itertools
-import objectmodel
-import matching
-
-from sepolgeni18n import _
-
 import copy
+import itertools
+
+from . import access
+from . import refpolicy
+from . import objectmodel
+from . import matching
+from .sepolgeni18n import _
+
 
 class Param:
     """
@@ -276,7 +276,7 @@
         if attributes:
             for typeattribute in interface.typeattributes():
                 for attr in typeattribute.attributes:
-                    if not attributes.attributes.has_key(attr):
+                    if attr not in attributes.attributes:
                         # print "missing attribute " + attr
                         continue
                     attr_vec = attributes.attributes[attr]
diff --git a/sepolgen/src/sepolgen/lex.py b/sepolgen/src/sepolgen/lex.py
index c149366..c13acef 100644
--- a/sepolgen/src/sepolgen/lex.py
+++ b/sepolgen/src/sepolgen/lex.py
@@ -26,18 +26,21 @@
 
 import re, sys, types
 
+from . import util
+import collections
+
+
 # Regular expression used to match valid token names
 _is_identifier = re.compile(r'^[a-zA-Z0-9_]+$')
 
-# Available instance types.  This is used when lexers are defined by a class.
-# It's a little funky because I want to preserve backwards compatibility
-# with Python 2.0 where types.ObjectType is undefined.
+# Available instance types.  This is used when parsers are defined by a class.
+# In Python3 the InstanceType and ObjectType are no more, they've passed, ceased
+# to be, they are ex-classes along with old-style classes
 
 try:
    _INSTANCETYPE = (types.InstanceType, types.ObjectType)
 except AttributeError:
-   _INSTANCETYPE = types.InstanceType
-   class object: pass       # Note: needed if no new-style classes present
+   _INSTANCETYPE = object
 
 # Exception thrown when invalid token encountered and no default error
 # handler is defined.
@@ -172,7 +175,7 @@
     # readtab() - Read lexer information from a tab file
     # ------------------------------------------------------------
     def readtab(self,tabfile,fdict):
-        exec "import %s as lextab" % tabfile
+        exec("import %s as lextab" % tabfile)
         self.lextokens      = lextab._lextokens
         self.lexreflags     = lextab._lexreflags
         self.lexliterals    = lextab._lexliterals
@@ -197,8 +200,8 @@
     # input() - Push a new string into the lexer
     # ------------------------------------------------------------
     def input(self,s):
-        if not (isinstance(s,types.StringType) or isinstance(s,types.UnicodeType)):
-            raise ValueError, "Expected a string"
+        if not (isinstance(s,util.bytes_type) or isinstance(s, util.string_type)):
+            raise ValueError("Expected a string")
         self.lexdata = s
         self.lexpos = 0
         self.lexlen = len(s)
@@ -207,8 +210,8 @@
     # begin() - Changes the lexing state
     # ------------------------------------------------------------
     def begin(self,state):
-        if not self.lexstatere.has_key(state):
-            raise ValueError, "Undefined state"
+        if state not in self.lexstatere:
+            raise ValueError("Undefined state")
         self.lexre = self.lexstatere[state]
         self.lexretext = self.lexstateretext[state]
         self.lexignore = self.lexstateignore.get(state,"")
@@ -286,7 +289,7 @@
                    break
 
                 # if func not callable, it means it's an ignored token                
-                if not callable(func):
+                if not isinstance(func, collections.Callable):
                    break 
 
                 # If token is processed by a function, call it
@@ -299,9 +302,9 @@
                 
                 # Verify type of the token.  If not in the token map, raise an error
                 if not self.lexoptimize:
-                    if not self.lextokens.has_key(newtok.type):
-                        raise LexError, ("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
-                            func.func_code.co_filename, func.func_code.co_firstlineno,
+                    if newtok.type not in self.lextokens:
+                        raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
+                            func.__code__.co_filename, func.__code__.co_firstlineno,
                             func.__name__, newtok.type),lexdata[lexpos:])
 
                 return newtok
@@ -329,17 +332,17 @@
                     newtok = self.lexerrorf(tok)
                     if lexpos == self.lexpos:
                         # Error method didn't change text position at all. This is an error.
-                        raise LexError, ("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
+                        raise LexError("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
                     lexpos = self.lexpos
                     if not newtok: continue
                     return newtok
 
                 self.lexpos = lexpos
-                raise LexError, ("Illegal character '%s' at index %d" % (lexdata[lexpos],lexpos), lexdata[lexpos:])
+                raise LexError("Illegal character '%s' at index %d" % (lexdata[lexpos],lexpos), lexdata[lexpos:])
 
         self.lexpos = lexpos + 1
         if self.lexdata is None:
-             raise RuntimeError, "No input string given with input()"
+             raise RuntimeError("No input string given with input()")
         return None
         
 # -----------------------------------------------------------------------------
@@ -377,7 +380,7 @@
             if not prev:
                 counthash[name] = linen
             else:
-                print "%s:%d: Rule %s redefined. Previously defined on line %d" % (filename,linen,name,prev)
+                print("%s:%d: Rule %s redefined. Previously defined on line %d" % (filename,linen,name,prev))
                 noerror = 0
         linen += 1
     return noerror
@@ -439,12 +442,12 @@
                 # callback function to carry out the action
                 if f.find("ignore_") > 0:
                     lexindexfunc[i] = (None,None)
-                    print "IGNORE", f
+                    print("IGNORE", f)
                 else:
                     lexindexfunc[i] = (None, f[2:])
          
         return [(lexre,lexindexfunc)],[regex]
-    except Exception,e:
+    except Exception as e:
         m = int(len(relist)/2)
         if m == 0: m = 1
         llist, lre = _form_master_re(relist[:m],reflags,ldict)
@@ -464,7 +467,7 @@
     nonstate = 1
     parts = s.split("_")
     for i in range(1,len(parts)):
-         if not names.has_key(parts[i]) and parts[i] != 'ANY': break
+         if parts[i] not in names and parts[i] != 'ANY': break
     if i > 1:
        states = tuple(parts[1:i])
     else:
@@ -507,7 +510,7 @@
             for (i,v) in _items:
                 ldict[i] = v
         else:
-            raise ValueError,"Expected a module or instance"
+            raise ValueError("Expected a module or instance")
         lexobj.lexmodule = module
         
     else:
@@ -542,61 +545,64 @@
         literals = ldict.get("literals","")
         
     if not tokens:
-        raise SyntaxError,"lex: module does not define 'tokens'"
-    if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
-        raise SyntaxError,"lex: tokens must be a list or tuple."
+        raise SyntaxError("lex: module does not define 'tokens'")
+    if not (isinstance(tokens,list) or isinstance(tokens,tuple)):
+        raise SyntaxError("lex: tokens must be a list or tuple.")
 
     # Build a dictionary of valid token names
     lexobj.lextokens = { }
     if not optimize:
         for n in tokens:
             if not _is_identifier.match(n):
-                print "lex: Bad token name '%s'" % n
+                print("lex: Bad token name '%s'" % n)
                 error = 1
-            if warn and lexobj.lextokens.has_key(n):
-                print "lex: Warning. Token '%s' multiply defined." % n
+            if warn and n in lexobj.lextokens:
+                print("lex: Warning. Token '%s' multiply defined." % n)
             lexobj.lextokens[n] = None
     else:
         for n in tokens: lexobj.lextokens[n] = None
 
     if debug:
-        print "lex: tokens = '%s'" % lexobj.lextokens.keys()
+        print("lex: tokens = '%s'" % list(lexobj.lextokens.keys()))
 
     try:
          for c in literals:
-               if not (isinstance(c,types.StringType) or isinstance(c,types.UnicodeType)) or len(c) > 1:
-                    print "lex: Invalid literal %s. Must be a single character" % repr(c)
+               if not (isinstance(c,util.bytes_type) or isinstance(c, util.string_type)) or len(c) > 1:
+                    print("lex: Invalid literal %s. Must be a single character" % repr(c))
                     error = 1
                     continue
 
     except TypeError:
-         print "lex: Invalid literals specification. literals must be a sequence of characters."
+         print("lex: Invalid literals specification. literals must be a sequence of characters.")
          error = 1
 
     lexobj.lexliterals = literals
 
     # Build statemap
     if states:
-         if not (isinstance(states,types.TupleType) or isinstance(states,types.ListType)):
-              print "lex: states must be defined as a tuple or list."
+         if not (isinstance(states,tuple) or isinstance(states,list)):
+              print("lex: states must be defined as a tuple or list.")
               error = 1
          else:
               for s in states:
-                    if not isinstance(s,types.TupleType) or len(s) != 2:
-                           print "lex: invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')" % repr(s)
+                    if not isinstance(s,tuple) or len(s) != 2:
+                           print("lex: invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')" % repr(s))
                            error = 1
                            continue
                     name, statetype = s
-                    if not isinstance(name,types.StringType):
-                           print "lex: state name %s must be a string" % repr(name)
+                    if isinstance(name, util.string_type):
+                           original_name = name
+                           name = util.encode_input(name)
+                    if not isinstance(name,util.bytes_type) or len(original_name) != len(name):
+                           print("lex: state name %s must be a byte string" % repr(original_name))
                            error = 1
                            continue
                     if not (statetype == 'inclusive' or statetype == 'exclusive'):
-                           print "lex: state type for state %s must be 'inclusive' or 'exclusive'" % name
+                           print("lex: state type for state %s must be 'inclusive' or 'exclusive'" % name)
                            error = 1
                            continue
-                    if stateinfo.has_key(name):
-                           print "lex: state '%s' already defined." % name
+                    if name in stateinfo:
+                           print("lex: state '%s' already defined." % name)
                            error = 1
                            continue
                     stateinfo[name] = statetype
@@ -618,28 +624,28 @@
     errorf   = { }        # Error functions by state
 
     if len(tsymbols) == 0:
-        raise SyntaxError,"lex: no rules of the form t_rulename are defined."
+        raise SyntaxError("lex: no rules of the form t_rulename are defined.")
 
     for f in tsymbols:
         t = ldict[f]
         states, tokname = _statetoken(f,stateinfo)
         toknames[f] = tokname
 
-        if callable(t):
+        if isinstance(t, collections.Callable):
             for s in states: funcsym[s].append((f,t))
-        elif (isinstance(t, types.StringType) or isinstance(t,types.UnicodeType)):
+        elif (isinstance(t, util.bytes_type) or isinstance(t,util.string_type)):
             for s in states: strsym[s].append((f,t))
         else:
-            print "lex: %s not defined as a function or string" % f
+            print("lex: %s not defined as a function or string" % f)
             error = 1
 
     # Sort the functions by line number
     for f in funcsym.values():
-        f.sort(lambda x,y: cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno))
+        f.sort(key=lambda x: x[1].__code__.co_firstlineno)
 
     # Sort the strings by regular expression length
     for s in strsym.values():
-        s.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1])))
+        s.sort(key=lambda x: len(x[1]))
 
     regexs = { }
 
@@ -649,31 +655,31 @@
 
         # Add rules defined by functions first
         for fname, f in funcsym[state]:
-            line = f.func_code.co_firstlineno
-            file = f.func_code.co_filename
+            line = f.__code__.co_firstlineno
+            file = f.__code__.co_filename
             files[file] = None
             tokname = toknames[fname]
 
             ismethod = isinstance(f, types.MethodType)
 
             if not optimize:
-                nargs = f.func_code.co_argcount
+                nargs = f.__code__.co_argcount
                 if ismethod:
                     reqargs = 2
                 else:
                     reqargs = 1
                 if nargs > reqargs:
-                    print "%s:%d: Rule '%s' has too many arguments." % (file,line,f.__name__)
+                    print("%s:%d: Rule '%s' has too many arguments." % (file,line,f.__name__))
                     error = 1
                     continue
 
                 if nargs < reqargs:
-                    print "%s:%d: Rule '%s' requires an argument." % (file,line,f.__name__)
+                    print("%s:%d: Rule '%s' requires an argument." % (file,line,f.__name__))
                     error = 1
                     continue
 
                 if tokname == 'ignore':
-                    print "%s:%d: Rule '%s' must be defined as a string." % (file,line,f.__name__)
+                    print("%s:%d: Rule '%s' must be defined as a string." % (file,line,f.__name__))
                     error = 1
                     continue
         
@@ -686,25 +692,25 @@
                     try:
                         c = re.compile("(?P<%s>%s)" % (f.__name__,f.__doc__), re.VERBOSE | reflags)
                         if c.match(""):
-                             print "%s:%d: Regular expression for rule '%s' matches empty string." % (file,line,f.__name__)
+                             print("%s:%d: Regular expression for rule '%s' matches empty string." % (file,line,f.__name__))
                              error = 1
                              continue
-                    except re.error,e:
-                        print "%s:%d: Invalid regular expression for rule '%s'. %s" % (file,line,f.__name__,e)
+                    except re.error as e:
+                        print("%s:%d: Invalid regular expression for rule '%s'. %s" % (file,line,f.__name__,e))
                         if '#' in f.__doc__:
-                             print "%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'." % (file,line, f.__name__)                 
+                             print("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'." % (file,line, f.__name__))
                         error = 1
                         continue
 
                     if debug:
-                        print "lex: Adding rule %s -> '%s' (state '%s')" % (f.__name__,f.__doc__, state)
+                        print("lex: Adding rule %s -> '%s' (state '%s')" % (f.__name__,f.__doc__, state))
 
                 # Okay. The regular expression seemed okay.  Let's append it to the master regular
                 # expression we're building
   
                 regex_list.append("(?P<%s>%s)" % (f.__name__,f.__doc__))
             else:
-                print "%s:%d: No regular expression defined for rule '%s'" % (file,line,f.__name__)
+                print("%s:%d: No regular expression defined for rule '%s'" % (file,line,f.__name__))
 
         # Now add all of the simple rules
         for name,r in strsym[state]:
@@ -716,34 +722,34 @@
 
             if not optimize:
                 if tokname == 'error':
-                    raise SyntaxError,"lex: Rule '%s' must be defined as a function" % name
+                    raise SyntaxError("lex: Rule '%s' must be defined as a function" % name)
                     error = 1
                     continue
         
-                if not lexobj.lextokens.has_key(tokname) and tokname.find("ignore_") < 0:
-                    print "lex: Rule '%s' defined for an unspecified token %s." % (name,tokname)
+                if tokname not in lexobj.lextokens and tokname.find("ignore_") < 0:
+                    print("lex: Rule '%s' defined for an unspecified token %s." % (name,tokname))
                     error = 1
                     continue
                 try:
                     c = re.compile("(?P<%s>%s)" % (name,r),re.VERBOSE | reflags)
                     if (c.match("")):
-                         print "lex: Regular expression for rule '%s' matches empty string." % name
+                         print("lex: Regular expression for rule '%s' matches empty string." % name)
                          error = 1
                          continue
-                except re.error,e:
-                    print "lex: Invalid regular expression for rule '%s'. %s" % (name,e)
+                except re.error as e:
+                    print("lex: Invalid regular expression for rule '%s'. %s" % (name,e))
                     if '#' in r:
-                         print "lex: Make sure '#' in rule '%s' is escaped with '\\#'." % name
+                         print("lex: Make sure '#' in rule '%s' is escaped with '\\#'." % name)
 
                     error = 1
                     continue
                 if debug:
-                    print "lex: Adding rule %s -> '%s' (state '%s')" % (name,r,state)
+                    print("lex: Adding rule %s -> '%s' (state '%s')" % (name,r,state))
                 
             regex_list.append("(?P<%s>%s)" % (name,r))
 
         if not regex_list:
-             print "lex: No rules defined for state '%s'" % state
+             print("lex: No rules defined for state '%s'" % state)
              error = 1
 
         regexs[state] = regex_list
@@ -755,7 +761,7 @@
                 error = 1
 
     if error:
-        raise SyntaxError,"lex: Unable to build lexer."
+        raise SyntaxError("lex: Unable to build lexer.")
 
     # From this point forward, we're reasonably confident that we can build the lexer.
     # No more errors will be generated, but there might be some warning messages.
@@ -768,7 +774,7 @@
         lexobj.lexstateretext[state] = re_text
         if debug:
             for i in range(len(re_text)):
-                 print "lex: state '%s'. regex[%d] = '%s'" % (state, i, re_text[i])
+                 print("lex: state '%s'. regex[%d] = '%s'" % (state, i, re_text[i]))
 
     # For inclusive states, we need to add the INITIAL state
     for state,type in stateinfo.items():
@@ -788,19 +794,19 @@
     lexobj.lexstateerrorf = errorf
     lexobj.lexerrorf = errorf.get("INITIAL",None)
     if warn and not lexobj.lexerrorf:
-        print "lex: Warning. no t_error rule is defined."
+        print("lex: Warning. no t_error rule is defined.")
 
     # Check state information for ignore and error rules
     for s,stype in stateinfo.items():
         if stype == 'exclusive':
-              if warn and not errorf.has_key(s):
-                   print "lex: Warning. no error rule is defined for exclusive state '%s'" % s
-              if warn and not ignore.has_key(s) and lexobj.lexignore:
-                   print "lex: Warning. no ignore rule is defined for exclusive state '%s'" % s
+              if warn and s not in errorf:
+                   print("lex: Warning. no error rule is defined for exclusive state '%s'" % s)
+              if warn and s not in ignore and lexobj.lexignore:
+                   print("lex: Warning. no ignore rule is defined for exclusive state '%s'" % s)
         elif stype == 'inclusive':
-              if not errorf.has_key(s):
+              if s not in errorf:
                    errorf[s] = errorf.get("INITIAL",None)
-              if not ignore.has_key(s):
+              if s not in ignore:
                    ignore[s] = ignore.get("INITIAL","")
    
 
@@ -829,7 +835,7 @@
             data = f.read()
             f.close()
         except IndexError:
-            print "Reading from standard input (type EOF to end):"
+            print("Reading from standard input (type EOF to end):")
             data = sys.stdin.read()
 
     if lexer:
@@ -845,7 +851,7 @@
     while 1:
         tok = _token()
         if not tok: break
-        print "(%s,%r,%d,%d)" % (tok.type, tok.value, tok.lineno,tok.lexpos)
+        print("(%s,%r,%d,%d)" % (tok.type, tok.value, tok.lineno,tok.lexpos))
         
 
 # -----------------------------------------------------------------------------
diff --git a/sepolgen/src/sepolgen/matching.py b/sepolgen/src/sepolgen/matching.py
index d56dd92..6f86359 100644
--- a/sepolgen/src/sepolgen/matching.py
+++ b/sepolgen/src/sepolgen/matching.py
@@ -21,33 +21,30 @@
 Classes and algorithms for matching requested access to access vectors.
 """
 
-import access
-import objectmodel
 import itertools
 
-class Match:
+from . import access
+from . import objectmodel
+from . import util
+
+
+class Match(util.Comparison):
     def __init__(self, interface=None, dist=0):
         self.interface = interface
         self.dist = dist
         self.info_dir_change = False
+        # when implementing __eq__ also __hash__ is needed on py2
+        # if object is muttable __hash__ should be None
+        self.__hash__ = None
 
-    def __cmp__(self, other):
-        if self.dist == other.dist:
-            if self.info_dir_change:
-                if other.info_dir_change:
-                    return 0
-                else:
-                    return 1
-            else:
-                if other.info_dir_change:
-                    return -1
-                else:
-                    return 0
-        else:
-            if self.dist < other.dist:
-                return -1
-            else:
-                return 1
+    def _compare(self, other, method):
+        try:
+            a = (self.dist, self.info_dir_change)
+            b = (other.dist, other.info_dir_change)
+            return method(a, b)
+        except (AttributeError, TypeError):
+            # trying to compare to foreign type
+            return NotImplemented
 
 class MatchList:
     DEFAULT_THRESHOLD = 150
diff --git a/sepolgen/src/sepolgen/module.py b/sepolgen/src/sepolgen/module.py
index 7fc9443..c09676a 100644
--- a/sepolgen/src/sepolgen/module.py
+++ b/sepolgen/src/sepolgen/module.py
@@ -22,17 +22,20 @@
 of module tress.
 """
 
-import defaults
+import re
+import tempfile
+try:
+    from subprocess import getstatusoutput
+except ImportError:
+    from commands import getstatusoutput
+import os
+import os.path
+import shutil
 
 import selinux
 
-import re
-import tempfile
-import commands
-import os
-import os.path
-import subprocess
-import shutil
+from . import defaults
+
 
 def is_valid_name(modname):
     """Check that a module name is valid.
@@ -130,7 +133,7 @@
 
     def run(self, command):
         self.o(command)
-        rc, output = commands.getstatusoutput(command)
+        rc, output = getstatusoutput(command)
         self.o(output)
         
         return rc
diff --git a/sepolgen/src/sepolgen/objectmodel.py b/sepolgen/src/sepolgen/objectmodel.py
index 88c8a1f..d05d721 100644
--- a/sepolgen/src/sepolgen/objectmodel.py
+++ b/sepolgen/src/sepolgen/objectmodel.py
@@ -118,7 +118,7 @@
                 continue
             if fields[0] == "class":
                 c = fields[1]
-                if self.classes.has_key(c):
+                if c in self.classes:
                     raise ValueError("duplicate class in perm map")
                 self.classes[c] = { }
                 cur = self.classes[c]
diff --git a/sepolgen/src/sepolgen/output.py b/sepolgen/src/sepolgen/output.py
index 739452d..7a83aee 100644
--- a/sepolgen/src/sepolgen/output.py
+++ b/sepolgen/src/sepolgen/output.py
@@ -27,8 +27,12 @@
 cleanly separated from the formatting issues.
 """
 
-import refpolicy
-import util
+from . import refpolicy
+from . import util
+
+if util.PY3:
+    from .util import cmp
+
 
 class ModuleWriter:
     def __init__(self):
@@ -127,7 +131,7 @@
         rules = []
         rules.extend(node.avrules())
         rules.extend(node.interface_calls())
-        rules.sort(rule_cmp)
+        rules.sort(key=util.cmp_to_key(rule_cmp))
 
         cur = None
         sep_rules = []
@@ -151,7 +155,7 @@
 
         ras = []
         ras.extend(node.role_types())
-        ras.sort(role_type_cmp)
+        ras.sort(key=util.cmp_to_key(role_type_cmp))
         if len(ras):
             comment = refpolicy.Comment()
             comment.lines.append("============= ROLES ==============")
diff --git a/sepolgen/src/sepolgen/policygen.py b/sepolgen/src/sepolgen/policygen.py
index 5f38577..4438a11 100644
--- a/sepolgen/src/sepolgen/policygen.py
+++ b/sepolgen/src/sepolgen/policygen.py
@@ -24,17 +24,20 @@
 import itertools
 import textwrap
 
-import refpolicy
-import objectmodel
-import access
-import interfaces
-import matching
 import selinux.audit2why as audit2why
 try:
     from setools import *
 except:
     pass
 
+from . import refpolicy
+from . import objectmodel
+from . import access
+from . import interfaces
+from . import matching
+from . import util
+if util.PY3:
+    from .util import cmp
 # Constants for the level of explanation from the generation
 # routines
 NO_EXPLANATION    = 0
@@ -167,14 +170,14 @@
 
             if av.type == audit2why.BOOLEAN:
                 if len(av.data) > 1:
-                    rule.comment += "\n#!!!! This avc can be allowed using one of the these booleans:\n#     %s" % ", ".join(map(lambda x: x[0], av.data))
+                    rule.comment += "\n#!!!! This avc can be allowed using one of the these booleans:\n#     %s" % ", ".join([x[0] for x in av.data])
                 else:
                     rule.comment += "\n#!!!! This avc can be allowed using the boolean '%s'" % av.data[0][0]
 
             if av.type == audit2why.CONSTRAINT:
                 rule.comment += "\n#!!!! This avc is a constraint violation.  You would need to modify the attributes of either the source or target types to allow this access."
                 rule.comment += "\n#Constraint rule: "
-                rule.comment += "\n\t" + av.data[0]
+                rule.comment += "\n#\t" + av.data[0]
                 for reason in av.data[1:]:
                     rule.comment += "\n#\tPossible cause is the source %s and target %s are different." % reason
 
@@ -186,7 +189,7 @@
                         self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"]
                     types=[]
 
-                    for i in map(lambda x: x[TCONTEXT], sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})):
+                    for i in [x[TCONTEXT] for x in sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})]:
                         if i not in self.domains:
                             types.append(i)
                     if len(types) == 1:
@@ -296,7 +299,7 @@
         elif params[i].type == refpolicy.OBJ_CLASS:
             ifcall.args.append(av.obj_class)
         else:
-            print params[i].type
+            print(params[i].type)
             assert(0)
 
     assert(len(ifcall.args) > 0)
diff --git a/sepolgen/src/sepolgen/refparser.py b/sepolgen/src/sepolgen/refparser.py
index 83542d3..3132c6f 100644
--- a/sepolgen/src/sepolgen/refparser.py
+++ b/sepolgen/src/sepolgen/refparser.py
@@ -34,12 +34,11 @@
 import re
 import traceback
 
-import refpolicy
-import access
-import defaults
-
-import lex
-import yacc
+from . import access
+from . import defaults
+from . import lex
+from . import refpolicy
+from . import yacc
 
 # :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 #
@@ -269,7 +268,7 @@
     t.lexer.lineno += 1
 
 def t_error(t):
-    print "Illegal character '%s'" % t.value[0]
+    print("Illegal character '%s'" % t.value[0])
     t.skip(1)
 
 def t_newline(t):
@@ -971,7 +970,7 @@
 def p_error(tok):
     global error, parse_file, success, parser
     error = "%s: Syntax error on line %d %s [type=%s]" % (parse_file, tok.lineno, tok.value, tok.type)
-    print error
+    print(error)
     success = False
 
 def prep_spt(spt):
@@ -1004,11 +1003,12 @@
     create_globals(module, support, debug)
     global error, parser, lexer, success
 
+    lexer.lineno = 1
     success = True
 
     try:
         parser.parse(text, debug=debug, lexer=lexer)
-    except Exception, e:
+    except Exception as e:
         parser = None
         lexer = None
         error = "internal parser error: %s" % str(e) + "\n" + traceback.format_exc()
@@ -1041,7 +1041,7 @@
 
 
 def parse_headers(root, output=None, expand=True, debug=False):
-    import util
+    from . import util
 
     headers = refpolicy.Headers()
 
@@ -1075,9 +1075,9 @@
             fd.close()
             parse_file = f
             parse(txt, module, spt, debug)
-        except IOError, e:
+        except IOError as e:
             return
-        except ValueError, e:
+        except ValueError as e:
             raise ValueError("error parsing file %s: %s" % (f, str(e)))
 
     spt = None
@@ -1113,7 +1113,7 @@
                 parse_file(x[1], m, spt)
             else:
                 parse_file(x[1], m)
-        except ValueError, e:
+        except ValueError as e:
             o(str(e) + "\n")
             failures.append(x[1])
             continue
diff --git a/sepolgen/src/sepolgen/refpolicy.py b/sepolgen/src/sepolgen/refpolicy.py
index b8ed5c1..737f956 100644
--- a/sepolgen/src/sepolgen/refpolicy.py
+++ b/sepolgen/src/sepolgen/refpolicy.py
@@ -18,7 +18,6 @@
 #
 
 import string
-import itertools
 import selinux
 
 # OVERVIEW
@@ -85,53 +84,53 @@
     # Top level nodes
 
     def nodes(self):
-        return itertools.ifilter(lambda x: isinstance(x, Node), walktree(self))
+        return filter(lambda x: isinstance(x, Node), walktree(self))
 
     def modules(self):
-        return itertools.ifilter(lambda x: isinstance(x, Module), walktree(self))
+        return filter(lambda x: isinstance(x, Module), walktree(self))
 
     def interfaces(self):
-        return itertools.ifilter(lambda x: isinstance(x, Interface), walktree(self))
+        return filter(lambda x: isinstance(x, Interface), walktree(self))
 
     def templates(self):
-        return itertools.ifilter(lambda x: isinstance(x, Template), walktree(self))
+        return filter(lambda x: isinstance(x, Template), walktree(self))
 
     def support_macros(self):
-        return itertools.ifilter(lambda x: isinstance(x, SupportMacros), walktree(self))
+        return filter(lambda x: isinstance(x, SupportMacros), walktree(self))
 
     # Common policy statements
 
     def module_declarations(self):
-        return itertools.ifilter(lambda x: isinstance(x, ModuleDeclaration), walktree(self))
+        return filter(lambda x: isinstance(x, ModuleDeclaration), walktree(self))
 
     def interface_calls(self):
-        return itertools.ifilter(lambda x: isinstance(x, InterfaceCall), walktree(self))
+        return filter(lambda x: isinstance(x, InterfaceCall), walktree(self))
 
     def avrules(self):
-        return itertools.ifilter(lambda x: isinstance(x, AVRule), walktree(self))
+        return filter(lambda x: isinstance(x, AVRule), walktree(self))
 
     def typerules(self):
-        return itertools.ifilter(lambda x: isinstance(x, TypeRule), walktree(self))
+        return filter(lambda x: isinstance(x, TypeRule), walktree(self))
 
     def typeattributes(self):
         """Iterate over all of the TypeAttribute children of this Interface."""
-        return itertools.ifilter(lambda x: isinstance(x, TypeAttribute), walktree(self))
+        return filter(lambda x: isinstance(x, TypeAttribute), walktree(self))
 
     def roleattributes(self):
         """Iterate over all of the RoleAttribute children of this Interface."""
-        return itertools.ifilter(lambda x: isinstance(x, RoleAttribute), walktree(self))
+        return filter(lambda x: isinstance(x, RoleAttribute), walktree(self))
 
     def requires(self):
-        return itertools.ifilter(lambda x: isinstance(x, Require), walktree(self))
+        return filter(lambda x: isinstance(x, Require), walktree(self))
 
     def roles(self):
-        return itertools.ifilter(lambda x: isinstance(x, Role), walktree(self))
+        return filter(lambda x: isinstance(x, Role), walktree(self))
 
     def role_allows(self):
-        return itertools.ifilter(lambda x: isinstance(x, RoleAllow), walktree(self))
+        return filter(lambda x: isinstance(x, RoleAllow), walktree(self))
 
     def role_types(self):
-        return itertools.ifilter(lambda x: isinstance(x, RoleType), walktree(self))
+        return filter(lambda x: isinstance(x, RoleType), walktree(self))
 
     def __str__(self):
         if self.comment:
@@ -291,7 +290,7 @@
         self.type = fields[2]
         if len(fields) > 3:
             # FUTURE - normalize level fields to allow more comparisons to succeed.
-            self.level = string.join(fields[3:], ':')
+            self.level = ':'.join(fields[3:])
         else:
             self.level = None
 
@@ -703,7 +702,7 @@
         s = ""
         for i in range(depth):
             s = s + "\t"
-        print s + str(node)
+        print(s + str(node))
 
 
 class Headers(Node):
@@ -810,7 +809,7 @@
         # are ordered correctly so that no macro is used before
         # it is defined
         s = set()
-        if self.map.has_key(perm):
+        if perm in self.map:
             for p in self.by_name(perm):
                 s.update(self.__expand_perm(p))
         else:
@@ -833,7 +832,7 @@
     def has_key(self, name):
         if not self.map:
             self.__gen_map()
-        return self.map.has_key(name)
+        return name in self.map
 
 class Require(Leaf):
     def __init__(self, parent=None):
diff --git a/sepolgen/src/sepolgen/util.py b/sepolgen/src/sepolgen/util.py
index 74a11f5..1fca971 100644
--- a/sepolgen/src/sepolgen/util.py
+++ b/sepolgen/src/sepolgen/util.py
@@ -16,6 +16,19 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 #
+import locale
+import sys
+
+
+PY3 = sys.version_info[0] == 3
+
+if PY3:
+    bytes_type=bytes
+    string_type=str
+else:
+    bytes_type=str
+    string_type=unicode
+
 
 class ConsoleProgressBar:
     def __init__(self, out, steps=100, indicator='#'):
@@ -76,6 +89,88 @@
         for x in s:
             return x
 
+def encode_input(text):
+    import locale
+    """Encode given text via preferred system encoding"""
+    # locale will often find out the correct encoding
+    encoding = locale.getpreferredencoding()
+    try:
+        encoded_text = text.encode(encoding)
+    except UnicodeError:
+    # if it fails to find correct encoding then ascii is used
+    # which may lead to UnicodeError if `text` contains non ascii signs
+    # utf-8 is our guess to fix the situation
+        encoded_text = text.encode('utf-8')
+    return encoded_text
+
+def decode_input(text):
+    import locale
+    """Decode given text via preferred system encoding"""
+    # locale will often find out the correct encoding
+    encoding = locale.getpreferredencoding()
+    try:
+        decoded_text = text.decode(encoding)
+    except UnicodeError:
+    # if it fails to find correct encoding then ascii is used
+    # which may lead to UnicodeError if `text` contains non ascii signs
+    # utf-8 is our guess to fix the situation
+        decoded_text = text.decode('utf-8')
+    return decoded_text
+
+class Comparison():
+    """Class used when implementing rich comparison.
+
+    Inherit from this class if you want to have a rich
+    comparison withing the class, afterwards implement
+    _compare function within your class."""
+
+    def _compare(self, other, method):
+        raise NotImplemented
+
+    def __eq__(self, other):
+        return self._compare(other, lambda a, b: a == b)
+
+    def __lt__(self, other):
+        return self._compare(other, lambda a, b: a < b)
+
+    def __le__(self, other):
+        return self._compare(other, lambda a, b: a <= b)
+
+    def __ge__(self, other):
+        return self._compare(other, lambda a, b: a >= b)
+
+    def __gt__(self, other):
+        return self._compare(other, lambda a, b: a > b)
+
+    def __ne__(self, other):
+        return self._compare(other, lambda a, b: a != b)
+
+if sys.version_info < (2,7):
+    # cmp_to_key function is missing in python2.6
+    def cmp_to_key(mycmp):
+        'Convert a cmp= function into a key= function'
+        class K:
+            def __init__(self, obj, *args):
+                self.obj = obj
+            def __lt__(self, other):
+                return mycmp(self.obj, other.obj) < 0
+            def __gt__(self, other):
+                return mycmp(self.obj, other.obj) > 0
+            def __eq__(self, other):
+                return mycmp(self.obj, other.obj) == 0
+            def __le__(self, other):
+                return mycmp(self.obj, other.obj) <= 0
+            def __ge__(self, other):
+                return mycmp(self.obj, other.obj) >= 0
+            def __ne__(self, other):
+                return mycmp(self.obj, other.obj) != 0
+        return K
+else:
+    from functools import cmp_to_key
+
+def cmp(first, second):
+    return (first > second) - (second > first)
+
 if __name__ == "__main__":
     import sys
     import time
diff --git a/sepolgen/src/sepolgen/yacc.py b/sepolgen/src/sepolgen/yacc.py
index bc4536d..f006354 100644
--- a/sepolgen/src/sepolgen/yacc.py
+++ b/sepolgen/src/sepolgen/yacc.py
@@ -67,7 +67,13 @@
 
 error_count = 3                # Number of symbols that must be shifted to leave recovery mode
 
-import re, types, sys, cStringIO, hashlib, os.path
+import re, types, sys, hashlib, os.path
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from io import StringIO
+
+from . import util
 
 # Exception raised for yacc-related errors
 class YaccError(Exception):   pass
@@ -109,7 +115,7 @@
         self.stack = stack
 
     def __getitem__(self,n):
-        if type(n) == types.IntType:
+        if type(n) == int:
              if n >= 0: return self.slice[n].value
              else: return self.stack[n].value
         else:
@@ -139,9 +145,9 @@
 
     def pushback(self,n):
         if n <= 0:
-            raise ValueError, "Expected a positive value"
+            raise ValueError("Expected a positive value")
         if n > (len(self.slice)-1):
-            raise ValueError, "Can't push %d tokens. Only %d are available." % (n,len(self.slice)-1)
+            raise ValueError("Can't push %d tokens. Only %d are available." % (n,len(self.slice)-1))
         for i in range(0,n):
             self.pbstack.append(self.slice[-i-1])
 
@@ -157,7 +163,7 @@
         # object directly.
 
         if magic != "xyzzy":
-            raise YaccError, "Can't instantiate Parser. Use yacc() instead."
+            raise YaccError("Can't instantiate Parser. Use yacc() instead.")
 
         # Reset internal state
         self.productions = None          # List of productions
@@ -190,7 +196,7 @@
 
         # If no lexer was given, we will try to use the lex module
         if not lexer:
-            import lex
+            from . import lex
             lexer = lex.lexer
 
         pslice.lexer = lexer
@@ -221,7 +227,7 @@
             # is already set, we just use that. Otherwise, we'll pull
             # the next token off of the lookaheadstack or from the lexer
             if debug > 1:
-                print 'state', statestack[-1]
+                print('state', statestack[-1])
             if not lookahead:
                 if not lookaheadstack:
                     lookahead = get_token()     # Get the next token
@@ -239,7 +245,7 @@
             t = actions.get((s,ltype),None)
 
             if debug > 1:
-                print 'action', t
+                print('action', t)
             if t is not None:
                 if t > 0:
                     # shift a symbol on the stack
@@ -396,7 +402,7 @@
                 continue
 
             # Call an error function here
-            raise RuntimeError, "yacc: internal parser error!!!\n"
+            raise RuntimeError("yacc: internal parser error!!!\n")
 
 # -----------------------------------------------------------------------------
 #                          === Parser Construction ===
@@ -457,12 +463,12 @@
 
         if n[0:2] == 'p_':
             sys.stderr.write("yacc: Warning. '%s' not defined as a function\n" % n)
-        if 1 and isinstance(v,types.FunctionType) and v.func_code.co_argcount == 1:
+        if 1 and isinstance(v,types.FunctionType) and v.__code__.co_argcount == 1:
             try:
                 doc = v.__doc__.split(" ")
                 if doc[1] == ':':
-                    sys.stderr.write("%s:%d: Warning. Possible grammar rule '%s' defined without p_ prefix.\n" % (v.func_code.co_filename, v.func_code.co_firstlineno,n))
-            except StandardError:
+                    sys.stderr.write("%s:%d: Warning. Possible grammar rule '%s' defined without p_ prefix.\n" % (v.__code__.co_filename, v.__code__.co_firstlineno,n))
+            except Exception:
                 pass
 
 # -----------------------------------------------------------------------------
@@ -514,8 +520,8 @@
 
     # File objects used when creating the parser.out debugging file
     global _vf, _vfc
-    _vf           = cStringIO.StringIO()
-    _vfc          = cStringIO.StringIO()
+    _vf           = StringIO()
+    _vfc          = StringIO()
 
 # -----------------------------------------------------------------------------
 # class Production:
@@ -581,7 +587,7 @@
         # Precompute list of productions immediately following
         try:
             p.lrafter = Prodnames[p.prod[n+1]]
-        except (IndexError,KeyError),e:
+        except (IndexError,KeyError) as e:
             p.lrafter = []
         try:
             p.lrbefore = p.prod[n-1]
@@ -615,7 +621,7 @@
 
 def add_production(f,file,line,prodname,syms):
     
-    if Terminals.has_key(prodname):
+    if prodname in Terminals:
         sys.stderr.write("%s:%d: Illegal rule name '%s'. Already defined as a token.\n" % (file,line,prodname))
         return -1
     if prodname == 'error':
@@ -634,7 +640,7 @@
                  if (len(c) > 1):
                       sys.stderr.write("%s:%d: Literal token %s in rule '%s' may only be a single character\n" % (file,line,s, prodname)) 
                       return -1
-                 if not Terminals.has_key(c):
+                 if c not in Terminals:
                       Terminals[c] = []
                  syms[x] = c
                  continue
@@ -646,7 +652,7 @@
 
     # See if the rule is already in the rulemap
     map = "%s -> %s" % (prodname,syms)
-    if Prodmap.has_key(map):
+    if map in Prodmap:
         m = Prodmap[map]
         sys.stderr.write("%s:%d: Duplicate rule %s.\n" % (file,line, m))
         sys.stderr.write("%s:%d: Previous definition at %s:%d\n" % (file,line, m.file, m.line))
@@ -663,7 +669,7 @@
             
     Productions.append(p)
     Prodmap[map] = p
-    if not Nonterminals.has_key(prodname):
+    if prodname not in Nonterminals:
         Nonterminals[prodname] = [ ]
     
     # Add all terminals to Terminals
@@ -687,13 +693,13 @@
             del p.prod[i]
             continue
 
-        if Terminals.has_key(t):
+        if t in Terminals:
             Terminals[t].append(p.number)
             # Is a terminal.  We'll assign a precedence to p based on this
             if not hasattr(p,"prec"):
                 p.prec = Precedence.get(t,('right',0))
         else:
-            if not Nonterminals.has_key(t):
+            if t not in Nonterminals:
                 Nonterminals[t] = [ ]
             Nonterminals[t].append(p.number)
         i += 1
@@ -722,8 +728,8 @@
 # and adds rules to the grammar
 
 def add_function(f):
-    line = f.func_code.co_firstlineno
-    file = f.func_code.co_filename
+    line = f.__code__.co_firstlineno
+    file = f.__code__.co_filename
     error = 0
 
     if isinstance(f,types.MethodType):
@@ -731,11 +737,11 @@
     else:
         reqdargs = 1
         
-    if f.func_code.co_argcount > reqdargs:
+    if f.__code__.co_argcount > reqdargs:
         sys.stderr.write("%s:%d: Rule '%s' has too many arguments.\n" % (file,line,f.__name__))
         return -1
 
-    if f.func_code.co_argcount < reqdargs:
+    if f.__code__.co_argcount < reqdargs:
         sys.stderr.write("%s:%d: Rule '%s' requires an argument.\n" % (file,line,f.__name__))
         return -1
           
@@ -776,7 +782,7 @@
                 error += e
 
                 
-            except StandardError:
+            except Exception:
                 sys.stderr.write("%s:%d: Syntax error in rule '%s'\n" % (file,dline,ps))
                 error -= 1
     else:
@@ -793,7 +799,7 @@
     (Unused terminals have already had their warning.)
     '''
     Reachable = { }
-    for s in Terminals.keys() + Nonterminals.keys():
+    for s in list(Terminals.keys()) + list(Nonterminals.keys()):
         Reachable[s] = 0
 
     mark_reachable_from( Productions[0].prod[0], Reachable )
@@ -872,7 +878,7 @@
     some_error = 0
     for (s,terminates) in Terminates.items():
         if not terminates:
-            if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
+            if s not in Prodnames and s not in Terminals and s != 'error':
                 # s is used-but-not-defined, and we've already warned of that,
                 # so it would be overkill to say that it's also non-terminating.
                 pass
@@ -893,7 +899,7 @@
         if not p: continue
 
         for s in p.prod:
-            if not Prodnames.has_key(s) and not Terminals.has_key(s) and s != 'error':
+            if s not in Prodnames and s not in Terminals and s != 'error':
                 sys.stderr.write("%s:%d: Symbol '%s' used, but not defined as a token or a rule.\n" % (p.file,p.line,s))
                 error = 1
                 continue
@@ -935,12 +941,12 @@
 
     if yaccdebug:
         _vf.write("\nTerminals, with rules where they appear\n\n")
-        ks = Terminals.keys()
+        ks = list(Terminals.keys())
         ks.sort()
         for k in ks:
             _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Terminals[k]])))
         _vf.write("\nNonterminals, with rules where they appear\n\n")
-        ks = Nonterminals.keys()
+        ks = list(Nonterminals.keys())
         ks.sort()
         for k in ks:
             _vf.write("%-20s : %s\n" % (k, " ".join([str(s) for s in Nonterminals[k]])))
@@ -1003,7 +1009,7 @@
                 sys.stderr.write("yacc: Invalid precedence '%s'\n" % prec)
                 return -1
             for t in terms:
-                if Precedence.has_key(t):
+                if t in Precedence:
                     sys.stderr.write("yacc: Precedence already specified for terminal '%s'\n" % t)
                     error += 1
                     continue
@@ -1087,7 +1093,7 @@
             # Here is the production set
             for i in range(len(p.prod)):
                 B = p.prod[i]
-                if Nonterminals.has_key(B):
+                if B in Nonterminals:
                     # Okay. We got a non-terminal in a production
                     fst = first(p.prod[i+1:])
                     hasempty = 0
@@ -1259,7 +1265,7 @@
         for x in asyms.keys():
             g = lr0_goto(I,x)
             if not g:  continue
-            if _lr0_cidhash.has_key(id(g)): continue
+            if id(g) in _lr0_cidhash: continue
             _lr0_cidhash[id(g)] = len(C)            
             C.append(g)
             
@@ -1305,7 +1311,7 @@
                 nullable[p.name] = 1
                 continue
            for t in p.prod:
-                if not nullable.has_key(t): break
+                if t not in nullable: break
            else:
                 nullable[p.name] = 1
        if len(nullable) == num_nullable: break
@@ -1329,7 +1335,7 @@
          for p in C[state]:
              if p.lr_index < p.len - 1:
                   t = (state,p.prod[p.lr_index+1])
-                  if Nonterminals.has_key(t[1]):
+                  if t[1] in Nonterminals:
                         if t not in trans: trans.append(t)
          state = state + 1
      return trans
@@ -1352,7 +1358,7 @@
     for p in g:
        if p.lr_index < p.len - 1:
            a = p.prod[p.lr_index+1]
-           if Terminals.has_key(a):
+           if a in Terminals:
                if a not in terms: terms.append(a)
 
     # This extra bit is to handle the start state
@@ -1377,7 +1383,7 @@
     for p in g:
         if p.lr_index < p.len - 1:
              a = p.prod[p.lr_index + 1]
-             if empty.has_key(a):
+             if a in empty:
                   rel.append((j,a))
 
     return rel
@@ -1437,15 +1443,15 @@
                  t = p.prod[lr_index]
 
                  # Check to see if this symbol and state are a non-terminal transition
-                 if dtrans.has_key((j,t)):
+                 if (j,t) in dtrans:
                        # Yes.  Okay, there is some chance that this is an includes relation
                        # the only way to know for certain is whether the rest of the 
                        # production derives empty
 
                        li = lr_index + 1
                        while li < p.len:
-                            if Terminals.has_key(p.prod[li]): break      # No forget it
-                            if not nullable.has_key(p.prod[li]): break
+                            if p.prod[li] in Terminals: break      # No forget it
+                            if p.prod[li] not in nullable: break
                             li = li + 1
                        else:
                             # Appears to be a relation between (j,t) and (state,N)
@@ -1466,7 +1472,7 @@
                  else:
                       lookb.append((j,r))
         for i in includes:
-             if not includedict.has_key(i): includedict[i] = []
+             if i not in includedict: includedict[i] = []
              includedict[i].append((state,N))
         lookdict[(state,N)] = lookb
 
@@ -1513,11 +1519,11 @@
         for a in F.get(y,[]):
             if a not in F[x]: F[x].append(a)
     if N[x] == d:
-       N[stack[-1]] = sys.maxint
+       N[stack[-1]] = sys.maxsize
        F[stack[-1]] = F[x]
        element = stack.pop()
        while element != x:
-           N[stack[-1]] = sys.maxint
+           N[stack[-1]] = sys.maxsize
            F[stack[-1]] = F[x]
            element = stack.pop()
 
@@ -1577,7 +1583,7 @@
     for trans,lb in lookbacks.items():
         # Loop over productions in lookback
         for state,p in lb:
-             if not p.lookaheads.has_key(state):
+             if state not in p.lookaheads:
                   p.lookaheads[state] = []
              f = followset.get(trans,[])
              for a in f:
@@ -1709,7 +1715,7 @@
                 else:
                     i = p.lr_index
                     a = p.prod[i+1]       # Get symbol right after the "."
-                    if Terminals.has_key(a):
+                    if a in Terminals:
                         g = lr0_goto(I,a)
                         j = _lr0_cidhash.get(id(g),-1)
                         if j >= 0:
@@ -1751,22 +1757,22 @@
                                 action[st,a] = j
                                 actionp[st,a] = p
                                 
-            except StandardError,e:
-                raise YaccError, "Hosed in lr_parse_table", e
+            except Exception as e:
+                raise YaccError("Hosed in lr_parse_table").with_traceback(e)
 
         # Print the actions associated with each terminal
         if yaccdebug:
           _actprint = { }
           for a,p,m in actlist:
-            if action.has_key((st,a)):
+            if (st,a) in action:
                 if p is actionp[st,a]:
                     _vf.write("    %-15s %s\n" % (a,m))
                     _actprint[(a,m)] = 1
           _vf.write("\n")
           for a,p,m in actlist:
-            if action.has_key((st,a)):
+            if (st,a) in action:
                 if p is not actionp[st,a]:
-                    if not _actprint.has_key((a,m)):
+                    if (a,m) not in _actprint:
                         _vf.write("  ! %-15s [ %s ]\n" % (a,m))
                         _actprint[(a,m)] = 1
             
@@ -1776,7 +1782,7 @@
         nkeys = { }
         for ii in I:
             for s in ii.usyms:
-                if Nonterminals.has_key(s):
+                if s in Nonterminals:
                     nkeys[s] = None
         for n in nkeys.keys():
             g = lr0_goto(I,n)
@@ -1914,15 +1920,14 @@
         
         f.close()
 
-    except IOError,e:
-        print "Unable to create '%s'" % filename
-        print e
-        return
+    except IOError as e:
+        print("Unable to create '%s'" % filename)
+        print(e)
 
 def lr_read_tables(module=tab_module,optimize=0):
     global _lr_action, _lr_goto, _lr_productions, _lr_method
     try:
-        exec "import %s as parsetab" % module
+        exec("import %s as parsetab" % module)
         
         if (optimize) or (Signature.digest() == parsetab._lr_signature):
             _lr_action = parsetab._lr_action
@@ -1938,13 +1943,13 @@
 
 
 # Available instance types.  This is used when parsers are defined by a class.
-# it's a little funky because I want to preserve backwards compatibility
-# with Python 2.0 where types.ObjectType is undefined.
+# In Python3 the InstanceType and ObjectType are no more, they've passed, ceased
+# to be, they are ex-classes along with old-style classes
 
 try:
    _INSTANCETYPE = (types.InstanceType, types.ObjectType)
 except AttributeError:
-   _INSTANCETYPE = types.InstanceType
+   _INSTANCETYPE = object
 
 # -----------------------------------------------------------------------------
 # yacc(module)
@@ -1962,7 +1967,7 @@
 
 
     # Add parsing method to signature
-    Signature.update(method)
+    Signature.update(util.encode_input(method))
     
     # If a "module" parameter was supplied, extract its dictionary.
     # Note: a module may in fact be an instance as well.
@@ -1977,7 +1982,7 @@
             for i in _items:
                 ldict[i[0]] = i[1]
         else:
-            raise ValueError,"Expected a module"
+            raise ValueError("Expected a module")
         
     else:
         # No module given.  We might be able to get information from the caller.
@@ -1995,7 +2000,7 @@
     if not start:
         start = ldict.get("start",None)
     if start:
-        Signature.update(start)
+        Signature.update(util.encode_input(start))
 
     # If running in optimized mode.  We're going to
 
@@ -2023,24 +2028,24 @@
             tokens = ldict.get("tokens",None)
     
         if not tokens:
-            raise YaccError,"module does not define a list 'tokens'"
-        if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
-            raise YaccError,"tokens must be a list or tuple."
+            raise YaccError("module does not define a list 'tokens'")
+        if not (isinstance(tokens,list) or isinstance(tokens,tuple)):
+            raise YaccError("tokens must be a list or tuple.")
 
         # Check to see if a requires dictionary is defined.
         requires = ldict.get("require",None)
         if requires:
-            if not (isinstance(requires,types.DictType)):
-                raise YaccError,"require must be a dictionary."
+            if not (isinstance(requires,dict)):
+                raise YaccError("require must be a dictionary.")
 
             for r,v in requires.items():
                 try:
-                    if not (isinstance(v,types.ListType)):
+                    if not (isinstance(v,list)):
                         raise TypeError
                     v1 = [x.split(".") for x in v]
                     Requires[r] = v1
-                except StandardError:
-                    print "Invalid specification for rule '%s' in require. Expected a list of strings" % r            
+                except Exception:
+                    print("Invalid specification for rule '%s' in require. Expected a list of strings" % r)
 
         
         # Build the dictionary of terminals.  We a record a 0 in the
@@ -2048,12 +2053,12 @@
         # used in the grammar
 
         if 'error' in tokens:
-            print "yacc: Illegal token 'error'.  Is a reserved word."
-            raise YaccError,"Illegal token name"
+            print("yacc: Illegal token 'error'.  Is a reserved word.")
+            raise YaccError("Illegal token name")
 
         for n in tokens:
-            if Terminals.has_key(n):
-                print "yacc: Warning. Token '%s' multiply defined." % n
+            if n in Terminals:
+                print("yacc: Warning. Token '%s' multiply defined." % n)
             Terminals[n] = [ ]
 
         Terminals['error'] = [ ]
@@ -2061,13 +2066,13 @@
         # Get the precedence map (if any)
         prec = ldict.get("precedence",None)
         if prec:
-            if not (isinstance(prec,types.ListType) or isinstance(prec,types.TupleType)):
-                raise YaccError,"precedence must be a list or tuple."
+            if not (isinstance(prec,list) or isinstance(prec,tuple)):
+                raise YaccError("precedence must be a list or tuple.")
             add_precedence(prec)
-            Signature.update(repr(prec))
+            Signature.update(util.encode_input(repr(prec)))
 
         for n in tokens:
-            if not Precedence.has_key(n):
+            if n not in Precedence:
                 Precedence[n] = ('right',0)         # Default, right associative, 0 precedence
 
         # Look for error handler
@@ -2078,17 +2083,17 @@
             elif isinstance(ef, types.MethodType):
                 ismethod = 1
             else:
-                raise YaccError,"'p_error' defined, but is not a function or method."                
-            eline = ef.func_code.co_firstlineno
-            efile = ef.func_code.co_filename
+                raise YaccError("'p_error' defined, but is not a function or method.")
+            eline = ef.__code__.co_firstlineno
+            efile = ef.__code__.co_filename
             files[efile] = None
 
-            if (ef.func_code.co_argcount != 1+ismethod):
-                raise YaccError,"%s:%d: p_error() requires 1 argument." % (efile,eline)
+            if (ef.__code__.co_argcount != 1+ismethod):
+                raise YaccError("%s:%d: p_error() requires 1 argument." % (efile,eline))
             global Errorfunc
             Errorfunc = ef
         else:
-            print "yacc: Warning. no p_error() function is defined."
+            print("yacc: Warning. no p_error() function is defined.")
             
         # Get the list of built-in functions with p_ prefix
         symbols = [ldict[f] for f in ldict.keys()
@@ -2097,27 +2102,27 @@
 
         # Check for non-empty symbols
         if len(symbols) == 0:
-            raise YaccError,"no rules of the form p_rulename are defined."
+            raise YaccError("no rules of the form p_rulename are defined.")
     
         # Sort the symbols by line number
-        symbols.sort(lambda x,y: cmp(x.func_code.co_firstlineno,y.func_code.co_firstlineno))
+        symbols.sort(key=lambda x: x.__code__.co_firstlineno)
 
         # Add all of the symbols to the grammar
         for f in symbols:
             if (add_function(f)) < 0:
                 error += 1
             else:
-                files[f.func_code.co_filename] = None
+                files[f.__code__.co_filename] = None
 
         # Make a signature of the docstrings
         for f in symbols:
             if f.__doc__:
-                Signature.update(f.__doc__)
+                Signature.update(util.encode_input(f.__doc__))
     
         lr_init_vars()
 
         if error:
-            raise YaccError,"Unable to construct parser."
+            raise YaccError("Unable to construct parser.")
 
         if not lr_read_tables(tabmodule):
 
@@ -2129,8 +2134,8 @@
             # Validate dictionary
             validate_dict(ldict)
 
-            if start and not Prodnames.has_key(start):
-                raise YaccError,"Bad starting symbol '%s'" % start
+            if start and start not in Prodnames:
+                raise YaccError("Bad starting symbol '%s'" % start)
         
             augment_grammar(start)    
             error = verify_productions(cycle_check=check_recursion)
@@ -2138,7 +2143,7 @@
                if (type(f) in (types.FunctionType,types.MethodType) and ldict[f].__name__[:2] != 'p_')]
 
             if error:
-                raise YaccError,"Unable to construct parser."
+                raise YaccError("Unable to construct parser.")
             
             build_lritems()
             compute_first1()
@@ -2147,7 +2152,7 @@
             if method in ['SLR','LALR']:
                 lr_parse_table(method)
             else:
-                raise YaccError, "Unknown parsing method '%s'" % method
+                raise YaccError("Unknown parsing method '%s'" % method)
 
             if write_tables:
                 lr_write_tables(tabmodule,outputdir)        
@@ -2159,8 +2164,8 @@
                     f.write("\n\n")
                     f.write(_vf.getvalue())
                     f.close()
-                except IOError,e:
-                    print "yacc: can't create '%s'" % debugfile,e
+                except IOError as e:
+                    print("yacc: can't create '%s'" % debugfile,e)
         
     # Made it here.   Create a parser object and set up its internal state.
     # Set global parse() method to bound method of parser object.
@@ -2205,5 +2210,5 @@
     
 # Stub that raises an error if parsing is attempted without first calling yacc()
 def parse(*args,**kwargs):
-    raise YaccError, "yacc: No parser built with yacc()"
+    raise YaccError("yacc: No parser built with yacc()")
 
diff --git a/sepolgen/tests/test_access.py b/sepolgen/tests/test_access.py
index fec699e..d45a823 100644
--- a/sepolgen/tests/test_access.py
+++ b/sepolgen/tests/test_access.py
@@ -32,7 +32,7 @@
         self.assertEqual(a.obj_class, None)
         self.assertTrue(isinstance(a.perms, refpolicy.IdSet))
         self.assertTrue(isinstance(a.audit_msgs, type([])))
-        self.assertEquals(len(a.audit_msgs), 0)
+        self.assertEqual(len(a.audit_msgs), 0)
 
         # Construction from a list
         a = access.AccessVector()
@@ -72,8 +72,10 @@
         self.assertEqual(l[0], "foo")
         self.assertEqual(l[1], "bar")
         self.assertEqual(l[2], "file")
-        self.assertEqual(l[3], "read")
-        self.assertEqual(l[4], "write")
+        perms = l[3:]
+        perms.sort()
+        self.assertEqual(perms[0], "read")
+        self.assertEqual(perms[1], "write")
 
     def test_to_string(self):
         a = access.AccessVector()
@@ -82,8 +84,21 @@
         a.obj_class = "file"
         a.perms.update(["read", "write"])
 
-        self.assertEquals(str(a), "allow foo bar:file { read write };")
-        self.assertEquals(a.to_string(), "allow foo bar:file { read write };")
+        first, second = str(a).split(':')
+        self.assertEqual(first, "allow foo bar")
+        second = second.split(' ')
+        second.sort()
+        expected = "file { read write };".split(' ')
+        expected.sort()
+        self.assertEqual(second, expected)
+
+        first, second = a.to_string().split(':')
+        self.assertEqual(first, "allow foo bar")
+        second = second.split(' ')
+        second.sort()
+        expected = "file { read write };".split(' ')
+        expected.sort()
+        self.assertEqual(second, expected)
 
     def test_cmp(self):
         a = access.AccessVector()
@@ -98,36 +113,38 @@
         b.obj_class = "file"
         b.perms.update(["read", "write"])
 
-        self.assertEquals(a, b)
+        self.assertEqual(a, b)
 
         # Source Type
         b.src_type = "baz"
-        self.assertEquals(cmp(a, b), 1)
+        self.assertNotEqual(a, b)
+        self.assertTrue(a > b)
 
         b.src_type = "gaz"
-        self.assertEquals(cmp(a, b), -1)
+        self.assertNotEqual(a, b)
+        self.assertTrue(a < b)
 
         # Target Type
         b.src_type = "foo"
         b.tgt_type = "aar"
-        self.assertEquals(cmp(a, b), 1)
+        self.assertNotEqual(a, b)
+        self.assertTrue(a > b)
 
         b.tgt_type = "gaz"
-        self.assertEquals(cmp(a, b), -1)
+        self.assertNotEqual(a, b)
+        self.assertTrue(a < b)
 
         # Perms
         b.tgt_type = "bar"
         b.perms = refpolicy.IdSet(["read"])
-        ret = cmp(a, b)
-        self.assertEquals(ret, 1)
+        self.assertNotEqual(a, b)
+        self.assertTrue(a > b)
 
         b.perms = refpolicy.IdSet(["read", "write", "append"])
-        ret = cmp(a, b)
-        self.assertEquals(ret, -1)
+        self.assertNotEqual(a, b)
 
         b.perms = refpolicy.IdSet(["read", "append"])
-        ret = cmp(a, b)
-        self.assertEquals(ret, 1)
+        self.assertNotEqual(a, b)
                          
 class TestUtilFunctions(unittest.TestCase):
     def test_is_idparam(self):
@@ -149,7 +166,7 @@
         rule.perms.add("write")
 
         avs = access.avrule_to_access_vectors(rule)
-        self.assertEquals(len(avs), 8)
+        self.assertEqual(len(avs), 8)
         comps = [("foo", "what", "dir"),
                  ("foo", "what", "file"),
                  ("foo", "bar", "dir"),
@@ -160,15 +177,15 @@
                  ("baz", "bar", "file")]
         status = [False] * 8
         for av in access.avrule_to_access_vectors(rule):
-            self.assertEquals(av.perms, refpolicy.IdSet(["read", "write"]))
-            for i in xrange(len(comps)):
+            self.assertEqual(av.perms, refpolicy.IdSet(["read", "write"]))
+            for i in range(len(comps)):
                 if comps[i][0] == av.src_type and \
                    comps[i][1] == av.tgt_type and \
                    comps[i][2] == av.obj_class:
                     status[i] = True
 
         for s in status:
-            self.assertEquals(s, True)
+            self.assertEqual(s, True)
                    
 
 class TestAccessVectorSet(unittest.TestCase):
@@ -203,18 +220,18 @@
                  ("baz", "bar", "file")]
         status = [False] * 8
         for av in self.s:
-            self.assertEquals(av.perms, refpolicy.IdSet(["read", "write"]))
-            for i in xrange(len(comps)):
+            self.assertEqual(av.perms, refpolicy.IdSet(["read", "write"]))
+            for i in range(len(comps)):
                 if comps[i][0] == av.src_type and \
                    comps[i][1] == av.tgt_type and \
                    comps[i][2] == av.obj_class:
                     status[i] = True
 
         for s in status:
-            self.assertEquals(s, True)
+            self.assertEqual(s, True)
 
     def test_len(self):
-        self.assertEquals(len(self.s), 8)
+        self.assertEqual(len(self.s), 8)
 
     def test_list(self):
         a = access.AccessVectorSet()
@@ -223,15 +240,22 @@
         a.add("what", "bar", "file", refpolicy.IdSet(["read", "write"]))
 
         avl = a.to_list()
+        avl.sort()
 
         test_l = [['what','bar','file','read','write'],
                   ['$1','foo','file','read','write'],
                   ['$1','bar','file','read','write']]
+        test_l.sort()
 
         for a,b in zip(test_l, avl):
             self.assertEqual(len(a), len(b))
-            for x,y in zip(a,b):
+            for x,y in list(zip(a,b))[:3]:
                 self.assertEqual(x, y)
+            perms1 = a[3:]
+            perms2 = b[3:]
+            perms1.sort()
+            perms2.sort()
+            self.assertEqual(perms1, perms2)
                 
         b = access.AccessVectorSet()
         b.from_list(avl)
diff --git a/sepolgen/tests/test_audit.py b/sepolgen/tests/test_audit.py
index 7b74220..6379954 100644
--- a/sepolgen/tests/test_audit.py
+++ b/sepolgen/tests/test_audit.py
@@ -60,29 +60,29 @@
     def test_defs(self):
         avc = sepolgen.audit.AVCMessage(audit1)
         sc = sepolgen.refpolicy.SecurityContext()
-        self.assertEquals(avc.scontext, sc)
-        self.assertEquals(avc.tcontext, sc)
-        self.assertEquals(avc.tclass, "")
-        self.assertEquals(avc.accesses, [])
+        self.assertEqual(avc.scontext, sc)
+        self.assertEqual(avc.tcontext, sc)
+        self.assertEqual(avc.tclass, "")
+        self.assertEqual(avc.accesses, [])
 
     def test_granted(self):
         avc = sepolgen.audit.AVCMessage(granted1)
         avc.from_split_string(granted1.split())
 
-        self.assertEquals(avc.scontext.user, "user_u")
-        self.assertEquals(avc.scontext.role, "system_r")
-        self.assertEquals(avc.scontext.type, "unconfined_t")
-        self.assertEquals(avc.scontext.level, "s0")
+        self.assertEqual(avc.scontext.user, "user_u")
+        self.assertEqual(avc.scontext.role, "system_r")
+        self.assertEqual(avc.scontext.type, "unconfined_t")
+        self.assertEqual(avc.scontext.level, "s0")
 
-        self.assertEquals(avc.tcontext.user, "user_u")
-        self.assertEquals(avc.tcontext.role, "object_r")
-        self.assertEquals(avc.tcontext.type, "user_home_t")
-        self.assertEquals(avc.tcontext.level, "s0")
+        self.assertEqual(avc.tcontext.user, "user_u")
+        self.assertEqual(avc.tcontext.role, "object_r")
+        self.assertEqual(avc.tcontext.type, "user_home_t")
+        self.assertEqual(avc.tcontext.level, "s0")
         
-        self.assertEquals(avc.tclass, "file")
-        self.assertEquals(avc.accesses, ["getattr"])
+        self.assertEqual(avc.tclass, "file")
+        self.assertEqual(avc.accesses, ["getattr"])
 
-        self.assertEquals(avc.denial, False)
+        self.assertEqual(avc.denial, False)
 
 
     def test_from_split_string(self):
@@ -91,54 +91,54 @@
         recs = audit1.split()
         avc.from_split_string(recs)
 
-        self.assertEquals(avc.header, "audit(1158064002.046:4):")
-        self.assertEquals(avc.scontext.user, "user_u")
-        self.assertEquals(avc.scontext.role, "system_r")
-        self.assertEquals(avc.scontext.type, "bluetooth_helper_t")
-        self.assertEquals(avc.scontext.level, "s0-s0:c0")
+        self.assertEqual(avc.header, "audit(1158064002.046:4):")
+        self.assertEqual(avc.scontext.user, "user_u")
+        self.assertEqual(avc.scontext.role, "system_r")
+        self.assertEqual(avc.scontext.type, "bluetooth_helper_t")
+        self.assertEqual(avc.scontext.level, "s0-s0:c0")
 
-        self.assertEquals(avc.tcontext.user, "system_u")
-        self.assertEquals(avc.tcontext.role, "object_r")
-        self.assertEquals(avc.tcontext.type, "xdm_tmp_t")
-        self.assertEquals(avc.tcontext.level, "s0")
+        self.assertEqual(avc.tcontext.user, "system_u")
+        self.assertEqual(avc.tcontext.role, "object_r")
+        self.assertEqual(avc.tcontext.type, "xdm_tmp_t")
+        self.assertEqual(avc.tcontext.level, "s0")
 
-        self.assertEquals(avc.tclass, "file")
-        self.assertEquals(avc.accesses, ["read"])
+        self.assertEqual(avc.tclass, "file")
+        self.assertEqual(avc.accesses, ["read"])
 
-        self.assertEquals(avc.comm, "bluez-pin")
+        self.assertEqual(avc.comm, "bluez-pin")
 
 
-        self.assertEquals(avc.denial, True)
+        self.assertEqual(avc.denial, True)
 
         # audit daemon message
         avc = sepolgen.audit.AVCMessage(audit2)
         recs = audit2.split()
         avc.from_split_string(recs)
 
-        self.assertEquals(avc.header, "audit(1158584779.745:708):")
-        self.assertEquals(avc.scontext.user, "user_u")
-        self.assertEquals(avc.scontext.role, "system_r")
-        self.assertEquals(avc.scontext.type, "vpnc_t")
-        self.assertEquals(avc.scontext.level, "s0")
+        self.assertEqual(avc.header, "audit(1158584779.745:708):")
+        self.assertEqual(avc.scontext.user, "user_u")
+        self.assertEqual(avc.scontext.role, "system_r")
+        self.assertEqual(avc.scontext.type, "vpnc_t")
+        self.assertEqual(avc.scontext.level, "s0")
 
-        self.assertEquals(avc.tcontext.user, "user_u")
-        self.assertEquals(avc.tcontext.role, "system_r")
-        self.assertEquals(avc.tcontext.type, "vpnc_t")
-        self.assertEquals(avc.tcontext.level, "s0")
+        self.assertEqual(avc.tcontext.user, "user_u")
+        self.assertEqual(avc.tcontext.role, "system_r")
+        self.assertEqual(avc.tcontext.type, "vpnc_t")
+        self.assertEqual(avc.tcontext.level, "s0")
 
-        self.assertEquals(avc.tclass, "capability")
-        self.assertEquals(avc.accesses, ["dac_read_search"])
+        self.assertEqual(avc.tclass, "capability")
+        self.assertEqual(avc.accesses, ["dac_read_search"])
 
-        self.assertEquals(avc.comm, "sh")
+        self.assertEqual(avc.comm, "sh")
 
-        self.assertEquals(avc.denial, True)
+        self.assertEqual(avc.denial, True)
 
 class TestPathMessage(unittest.TestCase):
     def test_from_split_string(self):
         path = sepolgen.audit.PathMessage(path1)
         recs = path1.split()
         path.from_split_string(recs)
-        self.assertEquals(path.path, "/usr/lib/sa/sa1")
+        self.assertEqual(path.path, "/usr/lib/sa/sa1")
 
 # TODO - add tests for the other message types
 
@@ -149,27 +149,28 @@
     def test_parse_string(self):
         a = sepolgen.audit.AuditParser()
         a.parse_string(log1)
-        self.assertEquals(len(a.avc_msgs), 11)
-        self.assertEquals(len(a.compute_sid_msgs), 0)
-        self.assertEquals(len(a.invalid_msgs), 0)
-        self.assertEquals(len(a.policy_load_msgs), 0)
-        self.assertEquals(len(a.path_msgs), 1)
+        self.assertEqual(len(a.avc_msgs), 11)
+        self.assertEqual(len(a.compute_sid_msgs), 0)
+        self.assertEqual(len(a.invalid_msgs), 0)
+        self.assertEqual(len(a.policy_load_msgs), 0)
+        self.assertEqual(len(a.path_msgs), 1)
 
     def test_post_process(self):
         a = sepolgen.audit.AuditParser()
         a.parse_string(log2)
-        self.assertEquals(len(a.avc_msgs), 2)
-        self.assertEquals(a.avc_msgs[0].path, "/usr/lib/sa/sa1")
-        self.assertEquals(a.avc_msgs[1].path, "/usr/lib/sa/sa1")
+        self.assertEqual(len(a.avc_msgs), 2)
+        self.assertEqual(a.avc_msgs[0].path, "/usr/lib/sa/sa1")
+        self.assertEqual(a.avc_msgs[1].path, "/usr/lib/sa/sa1")
 
     def test_parse_file(self):
         f = open("audit.txt")
         a = sepolgen.audit.AuditParser()
         a.parse_file(f)
-        self.assertEquals(len(a.avc_msgs), 21)
-        self.assertEquals(len(a.compute_sid_msgs), 0)
-        self.assertEquals(len(a.invalid_msgs), 0)
-        self.assertEquals(len(a.policy_load_msgs), 0)
+        f.close()
+        self.assertEqual(len(a.avc_msgs), 21)
+        self.assertEqual(len(a.compute_sid_msgs), 0)
+        self.assertEqual(len(a.invalid_msgs), 0)
+        self.assertEqual(len(a.policy_load_msgs), 0)
 
 class TestGeneration(unittest.TestCase):
     def test_generation(self):
diff --git a/sepolgen/tests/test_interfaces.py b/sepolgen/tests/test_interfaces.py
index b589bdf..a55f7db 100644
--- a/sepolgen/tests/test_interfaces.py
+++ b/sepolgen/tests/test_interfaces.py
@@ -202,11 +202,11 @@
         i = interfaces.InterfaceSet()
         i.add_headers(h)
 
-        self.assertEquals(len(i.interfaces), 1)
+        self.assertEqual(len(i.interfaces), 1)
         for key, interface in i.interfaces.items():
-            self.assertEquals(key, interface.name)
-            self.assertEquals(key, "foo")
-            self.assertEquals(len(interface.access), 2)
+            self.assertEqual(key, interface.name)
+            self.assertEqual(key, "foo")
+            self.assertEqual(len(interface.access), 2)
 
             # Check the access vectors
             comp_avs = [["$1", "usr_t", "dir", "create", "add_name"],
@@ -215,21 +215,21 @@
             self.assertTrue(ret)
 
             # Check the params
-            self.assertEquals(len(interface.params), 1)
+            self.assertEqual(len(interface.params), 1)
             for param in interface.params.values():
-                self.assertEquals(param.type, refpolicy.SRC_TYPE)
-                self.assertEquals(param.name, "$1")
-                self.assertEquals(param.num, 1)
-                self.assertEquals(param.required, True)
+                self.assertEqual(param.type, refpolicy.SRC_TYPE)
+                self.assertEqual(param.name, "$1")
+                self.assertEqual(param.num, 1)
+                self.assertEqual(param.required, True)
 
     def test_expansion(self):
         h = refparser.parse(test_expansion)
         i = interfaces.InterfaceSet()
         i.add_headers(h)
 
-        self.assertEquals(len(i.interfaces), 3)
+        self.assertEqual(len(i.interfaces), 3)
         for key, interface in i.interfaces.items():
-            self.assertEquals(key, interface.name)
+            self.assertEqual(key, interface.name)
             if key == "foo":
                 comp_avs = [["$1", "usr_t", "dir", "create", "add_name"],
                             ["$1", "usr_t", "file", "read", "write"]]
@@ -268,6 +268,7 @@
         i2 = interfaces.InterfaceSet()
         f = open("output")
         i2.from_file(f)
+        f.close()
         if_status = [False, False, False]
         for ifv in i2.interfaces.values():
             if ifv.name == "files_search_usr":
@@ -277,6 +278,6 @@
             if ifv.name == "files_exec_usr_files":
                 if_status[2] = True
 
-        self.assertEquals(if_status[0], True)
-        self.assertEquals(if_status[1], True)
-        self.assertEquals(if_status[2], True)
+        self.assertEqual(if_status[0], True)
+        self.assertEqual(if_status[1], True)
+        self.assertEqual(if_status[2], True)
diff --git a/sepolgen/tests/test_matching.py b/sepolgen/tests/test_matching.py
index 161e001..3ecb80b 100644
--- a/sepolgen/tests/test_matching.py
+++ b/sepolgen/tests/test_matching.py
@@ -33,15 +33,15 @@
         b.dist = 100
         b.info_dir_change = True
 
-        self.assertEquals(a, b)
+        self.assertEqual(a, b)
         b.info_dir_change = False
-        self.assertEquals(cmp(a, b), 1)
-        self.assertEquals(cmp(b, a), -1)
+        self.assertTrue((a > b))
+        self.assertTrue((b < a))
 
         b.dist = 200
 
-        self.assertEquals(cmp(a, b), -1)
-        self.assertEquals(cmp(b, a), 1)
+        self.assertTrue((a < b))
+        self.assertTrue((b > a))
 
 class TestMatchList(unittest.TestCase):
     def test_append(self):
@@ -90,7 +90,7 @@
         for x, y in zip(l, ml):
             self.assertEqual(x, y)
 
-        self.assertEquals(ml.best(), c)
+        self.assertEqual(ml.best(), c)
 
 
 test_expansion = """
diff --git a/sepolgen/tests/test_objectmodel.py b/sepolgen/tests/test_objectmodel.py
index 3db241c..b503672 100644
--- a/sepolgen/tests/test_objectmodel.py
+++ b/sepolgen/tests/test_objectmodel.py
@@ -25,20 +25,21 @@
         info = sepolgen.objectmodel.PermMappings()
         fd = open("perm_map")
         info.from_file(fd)
+        fd.close()
 
         pm = info.get("filesystem", "mount")
-        self.assertEquals(pm.perm, "mount")
-        self.assertEquals(pm.dir, sepolgen.objectmodel.FLOW_WRITE)
-        self.assertEquals(pm.weight, 1)
+        self.assertEqual(pm.perm, "mount")
+        self.assertEqual(pm.dir, sepolgen.objectmodel.FLOW_WRITE)
+        self.assertEqual(pm.weight, 1)
 
         self.assertRaises(KeyError, info.get, "filesystem", "foo")
 
         pm = info.getdefault("filesystem", "foo")
-        self.assertEquals(pm.perm, "foo")
-        self.assertEquals(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
-        self.assertEquals(pm.weight, 5)
+        self.assertEqual(pm.perm, "foo")
+        self.assertEqual(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
+        self.assertEqual(pm.weight, 5)
 
         pm = info.getdefault("foo", "bar")
-        self.assertEquals(pm.perm, "bar")
-        self.assertEquals(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
-        self.assertEquals(pm.weight, 5)
+        self.assertEqual(pm.perm, "bar")
+        self.assertEqual(pm.dir, sepolgen.objectmodel.FLOW_BOTH)
+        self.assertEqual(pm.weight, 5)
diff --git a/sepolgen/tests/test_refparser.py b/sepolgen/tests/test_refparser.py
index 3fe6d79..d7db145 100644
--- a/sepolgen/tests/test_refparser.py
+++ b/sepolgen/tests/test_refparser.py
@@ -107,12 +107,12 @@
         h = refparser.parse(interface_example)
         #print ""
         #refpolicy.print_tree(h)
-        #self.assertEquals(len(h.interfaces), 3)
+        #self.assertEqual(len(h.interfaces), 3)
 
         name = "files_search_usr"
         #i = h.interfaces[name]
-        #self.assertEquals(i.name, name)
-        #self.assertEquals(len(i.rules), 1)
+        #self.assertEqual(i.name, name)
+        #self.assertEqual(len(i.rules), 1)
         #rule = i.rules[0]
         #self.assertTrue(isinstance(rule, refpolicy.AVRule))
         
diff --git a/sepolgen/tests/test_refpolicy.py b/sepolgen/tests/test_refpolicy.py
index 8c87189..16e6680 100644
--- a/sepolgen/tests/test_refpolicy.py
+++ b/sepolgen/tests/test_refpolicy.py
@@ -24,10 +24,14 @@
 class TestIdSet(unittest.TestCase):
     def test_set_to_str(self):
         s = refpolicy.IdSet(["read", "write", "getattr"])
-        self.assertEquals(s.to_space_str(), "{ read write getattr }")
+        s = s.to_space_str().split(' ')
+        s.sort()
+        expected = "{ read write getattr }".split(' ')
+        expected.sort()
+        self.assertEqual(s, expected)
         s = refpolicy.IdSet()
         s.add("read")
-        self.assertEquals(s.to_space_str(), "read")
+        self.assertEqual(s.to_space_str(), "read")
 
 class TestSecurityContext(unittest.TestCase):
     def test_init(self):
@@ -38,25 +42,25 @@
         context = "user_u:object_r:foo_t"
         sc = refpolicy.SecurityContext()
         sc.from_string(context)
-        self.assertEquals(sc.user, "user_u")
-        self.assertEquals(sc.role, "object_r")
-        self.assertEquals(sc.type, "foo_t")
-        self.assertEquals(sc.level, None)
+        self.assertEqual(sc.user, "user_u")
+        self.assertEqual(sc.role, "object_r")
+        self.assertEqual(sc.type, "foo_t")
+        self.assertEqual(sc.level, None)
         if selinux.is_selinux_mls_enabled():
-            self.assertEquals(str(sc), context + ":s0")
+            self.assertEqual(str(sc), context + ":s0")
         else:
-            self.assertEquals(str(sc), context)
-        self.assertEquals(sc.to_string(default_level="s1"), context + ":s1")
+            self.assertEqual(str(sc), context)
+        self.assertEqual(sc.to_string(default_level="s1"), context + ":s1")
 
         context = "user_u:object_r:foo_t:s0-s0:c0-c255"
         sc = refpolicy.SecurityContext()
         sc.from_string(context)
-        self.assertEquals(sc.user, "user_u")
-        self.assertEquals(sc.role, "object_r")
-        self.assertEquals(sc.type, "foo_t")
-        self.assertEquals(sc.level, "s0-s0:c0-c255")
-        self.assertEquals(str(sc), context)
-        self.assertEquals(sc.to_string(), context)
+        self.assertEqual(sc.user, "user_u")
+        self.assertEqual(sc.role, "object_r")
+        self.assertEqual(sc.type, "foo_t")
+        self.assertEqual(sc.level, "s0-s0:c0-c255")
+        self.assertEqual(str(sc), context)
+        self.assertEqual(sc.to_string(), context)
 
         sc = refpolicy.SecurityContext()
         self.assertRaises(ValueError, sc.from_string, "abc")
@@ -67,20 +71,20 @@
         sc3 = refpolicy.SecurityContext("user_u:object_r:foo_t:s0")
         sc4 = refpolicy.SecurityContext("user_u:object_r:bar_t")
 
-        self.assertEquals(sc1, sc2)
-        self.assertNotEquals(sc1, sc3)
-        self.assertNotEquals(sc1, sc4)
+        self.assertEqual(sc1, sc2)
+        self.assertNotEqual(sc1, sc3)
+        self.assertNotEqual(sc1, sc4)
 
 class TestObjecClass(unittest.TestCase):
     def test_init(self):
         o = refpolicy.ObjectClass(name="file")
-        self.assertEquals(o.name, "file")
+        self.assertEqual(o.name, "file")
         self.assertTrue(isinstance(o.perms, set))
 
 class TestAVRule(unittest.TestCase):
     def test_init(self):
         a = refpolicy.AVRule()
-        self.assertEquals(a.rule_type, a.ALLOW)
+        self.assertEqual(a.rule_type, a.ALLOW)
         self.assertTrue(isinstance(a.src_types, set))
         self.assertTrue(isinstance(a.tgt_types, set))
         self.assertTrue(isinstance(a.obj_classes, set))
@@ -92,7 +96,7 @@
         a.tgt_types.add("bar_t")
         a.obj_classes.add("file")
         a.perms.add("read")
-        self.assertEquals(a.to_string(), "allow foo_t bar_t:file read;")
+        self.assertEqual(a.to_string(), "allow foo_t bar_t:file read;")
 
         a.rule_type = a.DONTAUDIT
         a.src_types.add("user_t")
@@ -100,17 +104,20 @@
         a.obj_classes.add("lnk_file")
         a.perms.add("write")
         # This test might need to go because set ordering is not guaranteed
-        self.assertEquals(a.to_string(),
-                          "dontaudit { foo_t user_t } { user_home_t bar_t }:{ lnk_file file } { read write };")
+        a = a.to_string().split(' ')
+        a.sort()
+        b = "dontaudit { foo_t user_t } { user_home_t bar_t }:{ lnk_file file } { read write };".split(' ')
+        b.sort()
+        self.assertEqual(a, b)
 
 class TestTypeRule(unittest.TestCase):
     def test_init(self):
         a = refpolicy.TypeRule()
-        self.assertEquals(a.rule_type, a.TYPE_TRANSITION)
+        self.assertEqual(a.rule_type, a.TYPE_TRANSITION)
         self.assertTrue(isinstance(a.src_types, set))
         self.assertTrue(isinstance(a.tgt_types, set))
         self.assertTrue(isinstance(a.obj_classes, set))
-        self.assertEquals(a.dest_type, "")
+        self.assertEqual(a.dest_type, "")
 
     def test_to_string(self):
         a = refpolicy.TypeRule()
@@ -118,7 +125,7 @@
         a.tgt_types.add("bar_exec_t")
         a.obj_classes.add("process")
         a.dest_type = "bar_t"
-        self.assertEquals(a.to_string(), "type_transition foo_t bar_exec_t:process bar_t;")
+        self.assertEqual(a.to_string(), "type_transition foo_t bar_exec_t:process bar_t;")
 
 
 class TestParseNode(unittest.TestCase):