void ElementGroup::ProcessComponent(const ComponentPtr& component, bool removable)
	{
		bool added = AddInspector(component, component->GetType(), removable);

		// If there wasn't a specific inspector for the given type, try adding interface inspectors
		if (!added)
		{
			// Make sure the transform inspector is at the top
			const auto& actualInterfaces = component->GetInterfaces();
			auto entry = actualInterfaces.find("ITransform");
			if (entry == actualInterfaces.end())
			{
				for (auto it = actualInterfaces.begin(), end = actualInterfaces.end(); it != end; ++it)
					added |= AddInspector(component, *it, removable);
			}
			else
			{
				AddInspector(component, "ITransform", false);

				std::set<std::string> interfacesMinusTransform = actualInterfaces;
				interfacesMinusTransform.erase("ITransform");
				for (auto it = interfacesMinusTransform.begin(), end = interfacesMinusTransform.end(); it != end; ++it)
					added |= AddInspector(component, *it, removable);
			}
		}
		if (!added)
			SendToConsole("No inspector for component type: " + component->GetType());
	}
	void CLRenderWorld::OnActivation(const ComponentPtr& component)
	{
		if (component->GetType() == "CLSprite")
		{
			auto sprite = boost::dynamic_pointer_cast<CLSprite>(component);
			if (sprite)
			{
				FSN_ASSERT(std::find(m_Drawables.begin(), m_Drawables.end(), sprite) == m_Drawables.end());
				m_Drawables.push_back(sprite);
				m_Sprites.push_back(sprite);
			}
		}
		if (component->GetType() == "StreamingCamera")
		{
			if (auto camComponent = boost::dynamic_pointer_cast<StreamingCamera>(component))
			{
				const bool shared = camComponent->GetSyncType() == ICamera::Shared;
				const bool synced = camComponent->GetParent()->IsSyncedEntity();

				if (synced)
				{
					// Shared cameras have no owner
					const PlayerID owner = shared ? 0 : camComponent->GetParent()->GetOwnerID();
					camComponent->m_Camera = m_CameraManager->GetCamera(camComponent->GetParent()->GetID(), owner);
				}
				else
				{
					// Attached to a pseudo-entity: create an un-synchronised camera
					camComponent->m_Camera = std::make_shared<Camera>();
					// Unsynchronised cameras are only useful for creating viewports at the moment
					SendToConsole("Warning: unsynchronised camera created: cameras attached to unsynchronised entities won't cause the map to load.");
				}

				if (shared || PlayerRegistry::IsLocal(camComponent->GetParent()->GetOwnerID()) || !synced)
				{
					if (camComponent->m_ViewportEnabled)
					{
						camComponent->m_Viewport = std::make_shared<Viewport>(camComponent->m_ViewportRect, camComponent->m_Camera);
						AddViewport(camComponent->m_Viewport);
					}
				}
				m_Cameras.push_back(camComponent);
			}
		}
	}
	void CLRenderWorld::OnDeactivation(const ComponentPtr& component)
	{
		auto drawable = boost::dynamic_pointer_cast<IDrawable>(component);
		if (drawable)
		{
			auto _where = std::find(m_Drawables.begin(), m_Drawables.end(), drawable);
			if (_where != m_Drawables.end())
			{
				m_Drawables.erase(_where);
			}

			auto sprite = boost::dynamic_pointer_cast<CLSprite>(component);
			if (sprite)
			{
				auto _where = std::find(m_Sprites.begin(), m_Sprites.end(), sprite);
				if (_where != m_Sprites.end())
				{
					m_Sprites.erase(_where);
				}
			}
		}
		else if (component->GetType() == "StreamingCamera")
		{
			if (auto camComponent = boost::dynamic_pointer_cast<StreamingCamera>(component))
			{
				if (camComponent->m_Viewport)
				{
					// Hack to remove viewport add operations from the queue
					std::vector<std::pair<ViewportPtr, bool>> keptViewportOps;
					std::pair<ViewportPtr, bool> viewportOperation;
					while (m_ViewportsToAddOrRemove.try_pop(viewportOperation))
					{
						if (viewportOperation.first != camComponent->m_Viewport)
							keptViewportOps.push_back(viewportOperation);
					}
					for (auto it = keptViewportOps.begin(); it != keptViewportOps.end(); ++it)
					{
						m_ViewportsToAddOrRemove.push(*it);
					}
					RemoveViewport(camComponent->m_Viewport);
					camComponent->m_Viewport.reset();
				}

				auto _where = std::find(m_Cameras.begin(), m_Cameras.end(), camComponent);
				if (_where != m_Cameras.end())
				{
					m_Cameras.erase(_where);
				}

				// If the component being deactivated should be kept active by this camera then
				//  it must have been removed
				if (camComponent->GetParent()->IsSyncedEntity())
				{
					const bool shared = camComponent->GetSyncType() == ICamera::Shared;
					const PlayerID owner = camComponent->GetParent()->GetOwnerID();
					if (shared || PlayerRegistry::IsLocal(owner))
					{
						m_CameraManager->RemoveCamera(camComponent->GetParent()->GetID());
					}
				}
			}
		}
	}