diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0242d976..bf38b34c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -57,13 +57,13 @@ set(libobjc_OBJCXX_SRCS
 	)
 set(libobjc_OBJC_SRCS 
 	NSBlocks.m
-	Protocol2.m
 	associate.m
 	blocks_runtime_np.m
 	properties.m)
 set(libobjc_C_SRCS 
 	alias_table.c
 	block_to_imp.c
+	builtin_classes.c
 	caps.c
 	category_loader.c
 	class_table.c
diff --git a/Protocol2.m b/Protocol2.m
deleted file mode 100644
index 154403ba..00000000
--- a/Protocol2.m
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "objc/runtime.h"
-#include "protocol.h"
-#include "class.h"
-#include <stdio.h>
-#include <string.h>
-
-@implementation Protocol
-// FIXME: This needs removing, but it's included for now because GNUstep's
-// implementation of +[NSObject conformsToProtocol:] calls it.
-- (BOOL)conformsTo: (Protocol*)p
-{
-	return protocol_conformsToProtocol(self, p);
-}
-- (id)retain
-{
-	return self;
-}
-- (void)release {}
-+ (Class)class { return self; }
-- (id)self { return self; }
-@end
-@interface __IncompleteProtocol : Protocol @end
-@implementation __IncompleteProtocol @end
-
-/**
- * This class exists for the sole reason that the legacy GNU ABI did not
- * provide a way of registering protocols with the runtime.  With the new ABI,
- * every protocol in a compilation unit that is not referenced should be added
- * in a category on this class.  This ensures that the runtime sees every
- * protocol at least once and can perform uniquing.
- */
-@interface __ObjC_Protocol_Holder_Ugly_Hack { id isa; } @end
-@implementation __ObjC_Protocol_Holder_Ugly_Hack @end
-
-@implementation Object @end
-
-@implementation ProtocolGCC @end
-@implementation ProtocolGSv1 @end
-
-PRIVATE void link_protocol_classes(void)
-{
-	[Protocol class];
-	[ProtocolGCC class];
-	[ProtocolGSv1 class];
-}
diff --git a/Test/PropertyIntrospectionTest2_arc.m b/Test/PropertyIntrospectionTest2_arc.m
index a0fe2e5c..0f8eb79c 100644
--- a/Test/PropertyIntrospectionTest2_arc.m
+++ b/Test/PropertyIntrospectionTest2_arc.m
@@ -302,7 +302,7 @@ static BOOL testPropertyForProperty_alt(objc_property_t p,
 	attrsList = property_copyAttributeList(p, NULL);
 	OPT_ASSERT(0 != attrsList);
 	objc_property_attribute_t *ra;
-	for (attrsCount = 0, ra = attrsList; (ra->name != NULL) && (attrsCount < size); attrsCount++, ra++) {}
+	for (attrsCount = 0, ra = attrsList; (attrsCount < size) && (ra->name != NULL) ; attrsCount++, ra++) {}
     OPT_ASSERT(attrsCount == size);
 	free(attrsList);
     for (unsigned int index=0; index<size; index++) {
diff --git a/builtin_classes.c b/builtin_classes.c
new file mode 100644
index 00000000..56879ef3
--- /dev/null
+++ b/builtin_classes.c
@@ -0,0 +1,106 @@
+#include "protocol.h"
+#include "class.h"
+#include "method.h"
+#include "loader.h"
+
+OBJC_PUBLIC struct objc_class _OBJC_CLASS_Object;
+
+static struct objc_class _OBJC_METACLASS_Object = {
+	.isa = NULL,
+	.name = "Object",
+	.info = objc_class_flag_meta,
+};
+OBJC_PUBLIC struct objc_class _OBJC_CLASS_Object = {
+	.isa = &_OBJC_METACLASS_Object,
+	.super_class = NULL,
+	.name = "Object",
+};
+
+static struct objc_class _OBJC_METACLASS_Protocol = {
+	.isa = &_OBJC_METACLASS_Object,
+	.super_class = &_OBJC_METACLASS_Object,
+	.name = "Protocol",
+	.info = objc_class_flag_meta,
+};
+static struct objc_class _OBJC_METACLASS_ProtocolGCC = {
+	.isa = &_OBJC_METACLASS_Object,
+	.super_class = &_OBJC_METACLASS_Object,
+	.name = "ProtocolGCC",
+	.info = objc_class_flag_meta,
+};
+static struct objc_class _OBJC_METACLASS_ProtocolGSv1 = {
+	.isa = &_OBJC_METACLASS_Object,
+	.super_class = &_OBJC_METACLASS_Object,
+	.name = "ProtocolGSv2",
+	.info = objc_class_flag_meta,
+};
+static struct objc_class _OBJC_METACLASS___IncompleteProtocol = {
+	.isa = &_OBJC_METACLASS_Object,
+	.super_class = &_OBJC_METACLASS_Object,
+	.name = "ProtocolGCC",
+	.info = objc_class_flag_meta,
+};
+
+OBJC_PUBLIC struct objc_class _OBJC_CLASS_Protocol = {
+	.isa = &_OBJC_METACLASS_Protocol,
+	.super_class = &_OBJC_CLASS_Object,
+	.name = "Protocol",
+	.info = objc_class_flag_permanent_instances,
+};
+
+OBJC_PUBLIC struct objc_class _OBJC_CLASS_ProtocolGCC = {
+	.isa = &_OBJC_METACLASS_ProtocolGCC,
+	.super_class = &_OBJC_CLASS_Protocol,
+	.name = "ProtocolGCC",
+	.info = objc_class_flag_permanent_instances,
+};
+
+OBJC_PUBLIC struct objc_class _OBJC_CLASS___IncompleteProtocol = {
+	.isa = &_OBJC_METACLASS_Protocol,
+	.super_class = &_OBJC_CLASS_Protocol,
+	.name = "__IncompleteProtocol",
+	.info = objc_class_flag_permanent_instances,
+};
+
+OBJC_PUBLIC struct objc_class _OBJC_CLASS_ProtocolGSv1 = {
+	.isa = &_OBJC_METACLASS_Protocol,
+	.super_class = &_OBJC_CLASS_Protocol,
+	.name = "ProtocolGSv1",
+	.info = objc_class_flag_permanent_instances,
+};
+
+#ifdef OLDABI_COMPAT
+static struct objc_class _OBJC_METACLASS___ObjC_Protocol_Holder_Ugly_Hack = {
+	.isa = NULL,
+	.name = "__ObjC_Protocol_Holder_Ugly_Hack",
+	.info = objc_class_flag_meta,
+};
+OBJC_PUBLIC struct objc_class _OBJC_CLASS__ObjC_Protocol_Holder_Ugly_Hack = {
+	.isa = &_OBJC_METACLASS___ObjC_Protocol_Holder_Ugly_Hack,
+	.super_class = NULL,
+	.name = "__ObjC_Protocol_Holder_Ugly_Hack",
+};
+#endif
+
+PRIVATE void init_builtin_classes(void)
+{
+	// Load the classes that are compiled into the runtime.
+	objc_load_class(&_OBJC_CLASS_Object);
+	objc_load_class(&_OBJC_CLASS_Protocol);
+	objc_load_class(&_OBJC_CLASS_ProtocolGCC);
+	objc_load_class(&_OBJC_CLASS_ProtocolGSv1);
+	objc_load_class(&_OBJC_CLASS___IncompleteProtocol);
+	objc_resolve_class(&_OBJC_CLASS_Object);
+	objc_resolve_class(&_OBJC_CLASS_Protocol);
+	objc_resolve_class(&_OBJC_CLASS_ProtocolGCC);
+	objc_resolve_class(&_OBJC_CLASS_ProtocolGSv1);
+	objc_resolve_class(&_OBJC_CLASS___IncompleteProtocol);
+	// Fix up the sizes of the various protocol classes that we will use.
+	_OBJC_CLASS_Object.instance_size = sizeof(void*);
+	_OBJC_CLASS_Protocol.instance_size = sizeof(struct objc_protocol);
+	_OBJC_CLASS___IncompleteProtocol.instance_size = sizeof(struct objc_protocol);
+#ifdef OLDABI_COMPAT
+	objc_load_class(&_OBJC_CLASS__ObjC_Protocol_Holder_Ugly_Hack);
+	objc_resolve_class(&_OBJC_CLASS__ObjC_Protocol_Holder_Ugly_Hack);
+#endif
+}
diff --git a/class.h b/class.h
index 0910d0b7..081feab4 100644
--- a/class.h
+++ b/class.h
@@ -462,6 +462,8 @@ void freeIvarLists(Class aClass);
  */
 void freeMethodLists(Class aClass);
 
+void objc_load_class(struct objc_class *cls);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/class_table.c b/class_table.c
index 3a6f1aa9..006b934b 100644
--- a/class_table.c
+++ b/class_table.c
@@ -137,6 +137,7 @@ PRIVATE Class class_table_next(void **e)
 			(struct class_table_internal_table_enumerator**)e);
 }
 
+PRIVATE BOOL objc_resolve_class(Class cls);
 PRIVATE void init_class_tables(void)
 {
 	class_table_internal_initialize(&class_table, 4096);
diff --git a/legacy.c b/legacy.c
index 51ae17b3..1ef1b810 100644
--- a/legacy.c
+++ b/legacy.c
@@ -7,6 +7,7 @@
 #include "objc/encoding.h"
 #include "legacy.h"
 #include "properties.h"
+#include "protocol.h"
 #include "class.h"
 #include "loader.h"
 
@@ -411,14 +412,13 @@ upgrade_protocol_method_list_gcc(struct objc_protocol_method_description_list_gc
 PRIVATE struct objc_protocol *objc_upgrade_protocol_gcc(struct objc_protocol_gcc *p)
 {
 	// If the protocol has already been upgraded, the don't try to upgrade it twice.
-	if (p->isa == objc_getClass("ProtocolGCC"))
+	if (p->isa == (id)&_OBJC_CLASS_ProtocolGCC)
 	{
 		return objc_getProtocol(p->name);
 	}
-	p->isa = objc_getClass("ProtocolGCC");
+	p->isa = (id)&_OBJC_CLASS_ProtocolGCC;
 	Protocol *proto =
-		(Protocol*)class_createInstance((Class)objc_getClass("Protocol"),
-				sizeof(struct objc_protocol) - sizeof(id));
+		(Protocol*)class_createInstance(&_OBJC_CLASS_Protocol, 0);
 	proto->name = p->name;
 	// Aliasing of this between the new and old structures means that when this
 	// returns these will all be updated.
@@ -432,13 +432,12 @@ PRIVATE struct objc_protocol *objc_upgrade_protocol_gcc(struct objc_protocol_gcc
 PRIVATE struct objc_protocol *objc_upgrade_protocol_gsv1(struct objc_protocol_gsv1 *p)
 {
 	// If the protocol has already been upgraded, the don't try to upgrade it twice.
-	if (p->isa == objc_getClass("ProtocolGSv1"))
+	if (p->isa == (id)&_OBJC_CLASS_ProtocolGSv1)
 	{
 		return objc_getProtocol(p->name);
 	}
 	Protocol *n =
-		(Protocol*)class_createInstance((Class)objc_getClass("Protocol"),
-				sizeof(struct objc_protocol) - sizeof(id));
+		(Protocol*)class_createInstance(&_OBJC_CLASS_Protocol, 0);
 	n->instance_methods = upgrade_protocol_method_list_gcc(p->instance_methods);
 	// Aliasing of this between the new and old structures means that when this
 	// returns these will all be updated.
@@ -447,14 +446,14 @@ PRIVATE struct objc_protocol *objc_upgrade_protocol_gsv1(struct objc_protocol_gs
 	n->class_methods = upgrade_protocol_method_list_gcc(p->class_methods);
 	n->properties = upgradePropertyList(p->properties);
 	n->optional_properties = upgradePropertyList(p->optional_properties);
-	n->isa = objc_getClass("Protocol");
+	n->isa = (id)&_OBJC_CLASS_Protocol;
 	// We do in-place upgrading of these, because they might be referenced
 	// directly
 	p->instance_methods = (struct objc_protocol_method_description_list_gcc*)n->instance_methods;
 	p->class_methods = (struct objc_protocol_method_description_list_gcc*)n->class_methods;
 	p->properties = (struct objc_property_list_gsv1*)n->properties;
 	p->optional_properties = (struct objc_property_list_gsv1*)n->optional_properties;
-	p->isa = objc_getClass("ProtocolGSv1");
+	p->isa = (id)&_OBJC_CLASS_ProtocolGSv1;
 	assert(p->isa);
 	return n;
 }
diff --git a/loader.c b/loader.c
index a49100a9..449d7a7c 100644
--- a/loader.c
+++ b/loader.c
@@ -19,17 +19,6 @@
 PRIVATE mutex_t runtime_mutex;
 LEGACY void *__objc_runtime_mutex = &runtime_mutex;
 
-void init_alias_table(void);
-void init_arc(void);
-void init_class_tables(void);
-void init_dispatch_tables(void);
-void init_gc(void);
-void init_protocol_table(void);
-void init_selector_tables(void);
-void init_trampolines(void);
-void init_early_blocks(void);
-void objc_send_load_message(Class class);
-
 void log_selector_memory_usage(void);
 
 static void log_memory_stats(void)
@@ -46,20 +35,11 @@ __attribute__((weak)) void (*dispatch_end_thread_4GC)(void);
 __attribute__((weak)) void *(*_dispatch_begin_NSAutoReleasePool)(void);
 __attribute__((weak)) void (*_dispatch_end_NSAutoReleasePool)(void *);
 
-__attribute__((used))
-static void link_protos(void)
-{
-	link_protocol_classes();
-}
-
 static void init_runtime(void)
 {
 	static BOOL first_run = YES;
 	if (first_run)
 	{
-#if ENABLE_GC
-		init_gc();
-#endif
 		// Create the main runtime lock.  This is not safe in theory, but in
 		// practice the first time that this function is called will be in the
 		// loader, from the main thread.  Future loaders may run concurrently,
@@ -80,6 +60,7 @@ static void init_runtime(void)
 		init_early_blocks();
 		init_arc();
 		init_trampolines();
+		init_builtin_classes();
 		first_run = NO;
 		if (getenv("LIBOBJC_MEMORY_PROFILE"))
 		{
@@ -253,22 +234,23 @@ OBJC_PUBLIC void __objc_load(struct objc_init *init)
 		assert(p);
 		*proto = p;
 	}
+	int classesLoaded = 0;
 	for (Class *cls = init->cls_begin ; cls < init->cls_end ; cls++)
 	{
 		if (*cls == NULL)
 		{
 			continue;
 		}
-		// As a special case, allow using legacy ABI code with a new runtime.
-		if (isFirstLoad && (strcmp((*cls)->name, "Protocol") == 0))
-		{
-			CurrentABI = UnknownABI;
-		}
 #ifdef DEBUG_LOADING
 		fprintf(stderr, "Loading class %s\n", (*cls)->name);
 #endif
 		objc_load_class(*cls);
 	}
+	if (isFirstLoad && (classesLoaded == 0))
+	{
+		// As a special case, allow using legacy ABI code with a new runtime.
+		CurrentABI = UnknownABI;
+	}
 #if 0
 	// We currently don't do anything with these pointers.  They exist to
 	// provide a level of indirection that will permit us to completely change
diff --git a/loader.h b/loader.h
index 21ff1d63..541c31ee 100644
--- a/loader.h
+++ b/loader.h
@@ -64,4 +64,63 @@ void objc_init_statics(struct objc_static_instance_list *statics);
  */
 void objc_init_buffered_statics(void);
 
+/**
+ * Initialise built-in classes (Object and Protocol).  This must be called
+ * after `init_class_tables`.
+ */
+void init_builtin_classes(void);
+
+/**
+ * Initialise the aliases table.
+ */
+void init_alias_table(void);
+
+/**
+ * Initialise the automatic reference counting system.
+ */
+void init_arc(void);
+
+/**
+ * Initialise the class tables.
+ */
+void init_class_tables(void);
+
+/**
+ * Initialise the dispatch table machinery.
+ */
+void init_dispatch_tables(void);
+
+/**
+ * Initialise the protocol tables.
+ */
+void init_protocol_table(void);
+
+/**
+ * Initialise the selector tables.
+ */
+void init_selector_tables(void);
+
+/**
+ * Initialise the trampolines for using blocks as methods.
+ */
+void init_trampolines(void);
+
+/**
+ * Send +load messages to a class if required.
+ */
+void objc_send_load_message(Class cls);
+
+/**
+ * Resolve a class (populate its superclass and sibling class links).  Returns
+ * YES if the class can be resolved, NO otherwise.  Classes cannot be resolved
+ * unless their superclasses have all been resolved.
+ */
+BOOL objc_resolve_class(Class cls);
+
+/**
+ * Initialise the block classes.
+ */
+void init_early_blocks(void);
+
+
 #endif //__OBJC_LOADER_H_INCLUDED
diff --git a/method.h b/method.h
index 4e2997bf..a155cb84 100644
--- a/method.h
+++ b/method.h
@@ -1,3 +1,4 @@
+#pragma once
 #include <assert.h>
 
 /**
diff --git a/protocol.c b/protocol.c
index e0144e24..bd13dad5 100644
--- a/protocol.c
+++ b/protocol.c
@@ -31,6 +31,8 @@ static int protocol_hash(const struct objc_protocol *protocol)
 static protocol_table *known_protocol_table;
 mutex_t protocol_table_lock;
 
+
+
 PRIVATE void init_protocol_table(void)
 {
 	protocol_initialize(&known_protocol_table, 128);
@@ -47,68 +49,14 @@ struct objc_protocol *protocol_for_name(const char *name)
 	return protocol_table_get(known_protocol_table, name);
 }
 
-static id incompleteProtocolClass(void)
-{
-	static id IncompleteProtocolClass = 0;
-	if (IncompleteProtocolClass == nil)
-	{
-		IncompleteProtocolClass = objc_getClass("__IncompleteProtocol");
-	}
-	return IncompleteProtocolClass;
-}
-
-/**
- * Class used for legacy GCC protocols (`ProtocolGCC`).
- */
-static id protocol_class_gcc;
-/**
- * Class used for legacy GNUstep V1 ABI  protocols (`ProtocolGSv1`).
- */
-static id protocol_class_gsv1;
-/**
- * Class used for protocols (`Protocol`).
- */
-static id protocol_class_gsv2;
-
-static BOOL init_protocol_classes(void)
-{
-	if (nil == protocol_class_gcc)
-	{
-		protocol_class_gcc = objc_getClass("ProtocolGCC");
-	}
-	if (nil == protocol_class_gsv1)
-	{
-		protocol_class_gsv1 = objc_getClass("ProtocolGSv1");
-	}
-	if (nil == protocol_class_gsv2)
-	{
-		protocol_class_gsv2 = objc_getClass("Protocol");
-	}
-	if ((nil == protocol_class_gcc) ||
-	    (nil == protocol_class_gsv1) ||
-	    (nil == protocol_class_gsv2))
-	{
-		return NO;
-	}
-	return YES;
-}
-
 static BOOL protocol_hasClassProperties(struct objc_protocol *p)
 {
-	if (!init_protocol_classes())
-	{
-		return NO;
-	}
-	return p->isa == protocol_class_gsv2;
+	return p->isa == (id)&_OBJC_CLASS_Protocol;
 }
 
 static BOOL protocol_hasOptionalMethodsAndProperties(struct objc_protocol *p)
 {
-	if (!init_protocol_classes())
-	{
-		return NO;
-	}
-	if (p->isa == protocol_class_gcc)
+	if (p->isa == (id)&_OBJC_CLASS_ProtocolGCC)
 	{
 		return NO;
 	}
@@ -198,18 +146,13 @@ static struct objc_protocol *unique_protocol(struct objc_protocol *aProto)
 
 static BOOL init_protocols(struct objc_protocol_list *protocols)
 {
-	if (!init_protocol_classes())
-	{
-		return NO;
-	}
-
 	for (unsigned i=0 ; i<protocols->count ; i++)
 	{
 		struct objc_protocol *aProto = protocols->list[i];
 		// Don't initialise a protocol twice
-		if ((aProto->isa == protocol_class_gcc) ||
-		    (aProto->isa == protocol_class_gsv1) ||
-		    (aProto->isa == protocol_class_gsv2))
+		if ((aProto->isa == (id)&_OBJC_CLASS_ProtocolGCC) ||
+		    (aProto->isa == (id)&_OBJC_CLASS_ProtocolGSv1) ||
+		    (aProto->isa == (id)&_OBJC_CLASS_Protocol))
 		{
 			continue;
 		}
@@ -226,19 +169,19 @@ static BOOL init_protocols(struct objc_protocol_list *protocols)
 #ifdef OLDABI_COMPAT
 			case protocol_version_gcc:
 				protocols->list[i] = objc_upgrade_protocol_gcc((struct objc_protocol_gcc *)aProto);
-				assert(aProto->isa == protocol_class_gcc);
-				assert(protocols->list[i]->isa == protocol_class_gsv2);
+				assert(aProto->isa == (id)&_OBJC_CLASS_ProtocolGCC);
+				assert(protocols->list[i]->isa == (id)&_OBJC_CLASS_Protocol);
 				aProto = protocols->list[i];
 				break;
 			case protocol_version_gsv1:
 				protocols->list[i] = objc_upgrade_protocol_gsv1((struct objc_protocol_gsv1 *)aProto);
-				assert(aProto->isa == protocol_class_gsv1);
-				assert(protocols->list[i]->isa == protocol_class_gsv2);
+				assert(aProto->isa == (id)&_OBJC_CLASS_ProtocolGSv1);
+				assert(protocols->list[i]->isa == (id)&_OBJC_CLASS_Protocol);
 				aProto = protocols->list[i];
 				break;
 #endif
 			case protocol_version_gsv2:
-				aProto->isa = protocol_class_gsv2;
+				aProto->isa = (id)&_OBJC_CLASS_Protocol;
 				break;
 		}
 		// Initialize all of the protocols that this protocol refers to
@@ -585,8 +528,7 @@ Protocol *objc_allocateProtocol(const char *name)
 {
 	if (objc_getProtocol(name) != NULL) { return NULL; }
 	// Create this as an object and add extra space at the end for the properties.
-	Protocol *p = (Protocol*)class_createInstance((Class)incompleteProtocolClass(),
-			sizeof(struct objc_protocol) - sizeof(id));
+	Protocol *p = (Protocol*)class_createInstance(&_OBJC_CLASS___IncompleteProtocol, 0);
 	p->name = strdup(name);
 	return p;
 }
@@ -595,16 +537,14 @@ void objc_registerProtocol(Protocol *proto)
 	if (NULL == proto) { return; }
 	LOCK_FOR_SCOPE(&protocol_table_lock);
 	if (objc_getProtocol(proto->name) != NULL) { return; }
-	if (incompleteProtocolClass() != proto->isa) { return; }
-	init_protocol_classes();
-	proto->isa = protocol_class_gsv2;
+	if (proto->isa != (id)&_OBJC_CLASS___IncompleteProtocol) { return; }
+	proto->isa = (id)&_OBJC_CLASS_Protocol;
 	protocol_table_insert(proto);
 }
 PRIVATE void registerProtocol(Protocol *proto)
 {
-	init_protocol_classes();
 	LOCK_FOR_SCOPE(&protocol_table_lock);
-	proto->isa = protocol_class_gsv2;
+	proto->isa = (id)&_OBJC_CLASS_Protocol;
 	if (protocol_for_name(proto->name) == NULL)
 	{
 		protocol_table_insert(proto);
@@ -617,7 +557,7 @@ void protocol_addMethodDescription(Protocol *aProtocol,
                                    BOOL isInstanceMethod)
 {
 	if ((NULL == aProtocol) || (NULL == name) || (NULL == types)) { return; }
-	if (incompleteProtocolClass() != aProtocol->isa) { return; }
+	if (aProtocol->isa != (id)(id)&_OBJC_CLASS___IncompleteProtocol) { return; }
 	struct objc_protocol_method_description_list **listPtr;
 	if (isInstanceMethod)
 	{
@@ -663,7 +603,7 @@ void protocol_addMethodDescription(Protocol *aProtocol,
 void protocol_addProtocol(Protocol *aProtocol, Protocol *addition)
 {
 	if ((NULL == aProtocol) || (NULL == addition)) { return; }
-	if (incompleteProtocolClass() != aProtocol->isa) { return; }
+	if (aProtocol->isa != (id)&_OBJC_CLASS___IncompleteProtocol) { return; }
 	if (NULL == aProtocol->protocol_list)
 	{
 		aProtocol->protocol_list = calloc(1, sizeof(struct objc_property_list) + sizeof(Protocol*));
@@ -685,7 +625,7 @@ void protocol_addProperty(Protocol *aProtocol,
                           BOOL isInstanceProperty)
 {
 	if ((NULL == aProtocol) || (NULL == name)) { return; }
-	if (incompleteProtocolClass() != aProtocol->isa) { return; }
+	if (aProtocol->isa != (id)&_OBJC_CLASS___IncompleteProtocol) { return; }
 	if (!isInstanceProperty) { return; }
 	struct objc_property_list **listPtr = 
 	    isInstanceProperty ?
diff --git a/protocol.h b/protocol.h
index 15a0838a..a5fd7ec7 100644
--- a/protocol.h
+++ b/protocol.h
@@ -187,22 +187,11 @@ struct objc_protocol_gsv1
 	struct objc_property_list_gsv1      *optional_properties;
 };
 
-#ifdef __OBJC__
-@interface Object { id isa; } @end
-/**
- * Definition of the Protocol type.  Protocols are objects, but are rarely used
- * as such.
- */
-@interface Protocol : Object
-@end
-
-@interface ProtocolGCC : Protocol
-@end
-
-@interface ProtocolGSv1 : Protocol
-@end
-
-#endif
+OBJC_PUBLIC extern struct objc_class _OBJC_CLASS_Object;
+OBJC_PUBLIC extern struct objc_class _OBJC_CLASS_Protocol;
+OBJC_PUBLIC extern struct objc_class _OBJC_CLASS___IncompleteProtocol;
+OBJC_PUBLIC extern struct objc_class _OBJC_CLASS_ProtocolGCC;
+OBJC_PUBLIC extern struct objc_class _OBJC_CLASS_ProtocolGSv1;
 
 /**
  * List of protocols.  Attached to a class or a category by the compiler and to
diff --git a/selector.h b/selector.h
index 10307492..c9409873 100644
--- a/selector.h
+++ b/selector.h
@@ -1,5 +1,7 @@
 #ifndef OBJC_SELECTOR_H_INCLUDED
 #define OBJC_SELECTOR_H_INCLUDED
+#include <stdint.h>
+#include "objc/runtime.h"
 
 /**
  * Structure used to store selectors in the list.