+@end
+
+static const char *CYBlockEncoding(NSBlock *self);
+static sig::Signature *CYBlockSignature(CYPool &pool, NSBlock *self);
+
+@implementation NSBlock (Cycript)
+
+- (NSString *) cy$toCYON:(bool)objective inSet:(std::set<void *> &)objects {
+ CYLocalPool pool;
+
+ sig::Signature *signature(CYBlockSignature(pool, self));
+ // XXX: I am checking signature->count due to Decode doing it for block_P
+ if (signature == NULL || signature->count == 0)
+ return [super cy$toCYON:objective inSet:objects];
+ _oassert(objects.insert(self).second);
+
+ // XXX: maybe move this id check into Decode's implementation for block_P
+ _assert(signature->count >= 2);
+ _assert(signature->elements[1].type->primitive == sig::object_P);
+
+ sig::Type type;
+ type.name = NULL;
+ type.flags = 0;
+
+ type.primitive = sig::function_P; // XXX: sig::block_P
+ sig::Copy(pool, type.data.signature, *signature);
+
+ CYTypedIdentifier *typed((new(pool) CYTypeExpression(Decode(pool, &type)))->typed_);
+ CYTypeFunctionWith *function(typed->Function());
+ _assert(function != NULL);
+
+ _assert(function->parameters_ != NULL);
+ CYObjCBlock *block(new(pool) CYObjCBlock(typed, function->parameters_->next_, NULL));
+
+ std::ostringstream str;
+ CYOptions options;
+ CYOutput out(*str.rdbuf(), options);
+ block->Output(out, CYNoFlags);
+
+ std::string value(str.str());
+ return CYCastNSString(NULL, CYUTF8String(value.c_str(), value.size()));
+}
+