GpsMarkerModule::GpsMarkerModule(Eegeo::Location::ILocationService& locationService,
                                             Eegeo::Modules::Map::Layers::TerrainModelModule& terrainModelModule,
                                             Eegeo::Modules::Map::MapModule& mapModule,
                                             Eegeo::Modules::Core::RenderingModule& renderingModule,
                                             Eegeo::Resources::Interiors::InteriorInteractionModel& interiorInteractionModel,
                                             VisualMap::SdkModel::IVisualMapService& visualMapService,
                                             const bool createBlueSphereViews,
                                             ExampleAppMessaging::TMessageBus& messageBus)
            : m_renderableFilters(renderingModule.GetRenderableFilters())
            {
                m_pModel = Eegeo_NEW(GpsMarkerModel)(locationService, interiorInteractionModel, mapModule.GetBlueSphereModule().GetBlueSphereModel());

                m_pRingRenderableFactory = AccuracyRingRenderableFactory::Create(renderingModule);
                m_pRingRenderable = m_pRingRenderableFactory->BuildRenderable();
                m_pRingRenderable->SetColors(Eegeo::v4(18.0f/255.0f, 86.0f/255.0f, 172.0f/255.0f, 0.75f),
                                             Eegeo::v4(18.0f/255.0f, 86.0f/255.0f, 172.0f/255.0f, 0.8f));
                m_pRingView = Eegeo_NEW(AccuracyRingView)(*m_pRingRenderable);

                m_renderableFilters.AddRenderableFilter(*m_pRingView);

                m_pController = Eegeo_NEW(GpsMarkerController)(*m_pModel,
                                                               interiorInteractionModel,
                                                               locationService,
                                                               mapModule.GetEnvironmentFlatteningService(),
                                                               visualMapService,
                                                               mapModule.GetBlueSphereModule().GetBlueSphereView(),
                                                               mapModule.GetBlueSphereModule().GetBlueSphereAnchorView(),
                                                               createBlueSphereViews,
                                                               *m_pRingView,
                                                               messageBus);
            }
void ModifiedRenderingExample::Start()
{
	//MyPoolFilterCriteria implemented below... uses camera interest point as selection criteria
	m_pCriteria = new ModifiedRenderingExample::MyPoolFilterCriteria(this);

	//apply to filter, but lifetime responsibility is ours
	m_buildingFilter.SetFilterCriteria(m_pCriteria);

	//register for notifications when scene elements are added to or removed from the scene.
	m_buildingRepository.AddObserver(*this);

	//register as a renderable filter so that we can submit our new renderables for rendering.
	m_renderableFilters.AddRenderableFilter(this);

	// create alternative material to render with.
	m_pAlternativeLighting = Eegeo_NEW(Eegeo::Lighting::GlobalLighting)();

	m_pAlternativeShader = Eegeo::Rendering::Shaders::PackedDiffuseShader::Create(m_shaderIdGenerator.GetNextId());

	m_pAlternativeMaterial = Eegeo_NEW(Eegeo::Rendering::Materials::PackedDiffuseMaterial)(
	                             m_materialIdGenerator.GetNextId(),
	                             "ExampleMaterial",
	                             *m_pAlternativeShader,
	                             *m_pAlternativeLighting,
	                             m_placeHolderTexture.textureId,
	                             Eegeo::Rendering::TextureMinify_NearestMipmap_Linear,
	                             false,
	                             false);
    
    PopulateAlternativeRenderablesFromInitialSceneGraph();
}
     WatermarkModule::WatermarkModule(Eegeo::Helpers::IIdentityProvider& identityProvider,
                                      const std::string& appName,
                                      const std::string& googleAnalyticsReferrerToken,
                                      Eegeo::Resources::Interiors::InteriorSelectionModel& interiorSelectionModel,
                                      Eegeo::Resources::Interiors::InteriorsModelRepository& interiorsModelRepository,
                                      InteriorsExplorer::SdkModel::InteriorsExplorerModel& interiorsExplorerModel,
                                      ExampleAppMessaging::TMessageBus& messageBus)
     {
         m_pViewModel = Eegeo_NEW(View::WatermarkViewModel)(identityProvider.GetNextIdentity(), false);
         
         m_pWatermarkDataFactory = Eegeo_NEW(View::WatermarkDataFactory)(appName, googleAnalyticsReferrerToken);
         
         m_pWatermarkDataRepository = Eegeo_NEW(View::WatermarkDataRepository)();
         
         m_pWatermarkDataRepository->AddWatermarkData("eegeo", m_pWatermarkDataFactory->CreateDefaultEegeo());
 
         m_pWatermarkModel = Eegeo_NEW(WatermarkModel)();
         
         m_pWatermarkInteriorStateChangedObserver = Eegeo_NEW(WatermarkInteriorStateChangedObserver)(*m_pWatermarkModel,
                                                                                                     interiorSelectionModel,
                                                                                                     interiorsModelRepository,
                                                                                                     interiorsExplorerModel,
                                                                                                     messageBus);
         AddThirdPartyWatermarkData();
     }
            WorldMenuController::WorldMenuController(IWorldMenuItemObservable& worldMenuItemObservable
                                                     , IWorldMenuItemViewFactory& viewFactory
                                                     , Eegeo::UI::IUIInteractionObservable& uiInteractionObservable
                                                     , Eegeo::UI::IUICameraProvider& uiCameraProvider
                                                     , Eegeo::UI::IUIQuadFactory& quadFactory
                                                     , Eegeo::UI::IUIRenderableFilter& uiRenderableFilter
                                                     , std::string texture
                                                     , int topSpriteID
                                                     , int numTilesAlong1Axes)
            : m_worldMenuItemRepository(worldMenuItemObservable)
            , m_viewFactory(viewFactory)
            , m_uiInteractionObservable(uiInteractionObservable)
            , m_uiCameraProvider(uiCameraProvider)
            {
                m_pWorldMenuUpView = Eegeo_NEW(WorldMenuUpView)(quadFactory, uiRenderableFilter, texture, topSpriteID, numTilesAlong1Axes);
                m_menuItemsShouldRender = true;
                m_isMenuShown = false;
                m_worldMenuItemRepository.AddWorldMenuObserver(this);
                Eegeo::v2 size(numTilesAlong1Axes,numTilesAlong1Axes);
                Eegeo::v2 outMin;
                Eegeo::v2 outMax;
                Eegeo::UI::CalculateUV(size, 20, outMin, outMax);

                Eegeo::v2 dimension = Eegeo::v2(50.f,50.f);
                m_pSelectedArrow = Eegeo_NEW(Eegeo::UI::UISprite)(uiRenderableFilter,
                                                                  quadFactory.CreateUIQuad(texture,
                                                                                           dimension,
                                                                                           outMin,
                                                                                           outMax,
                                                                                           Eegeo::Rendering::LayerIds::Values::AfterAll),
                                                                  dimension);
                m_pSelectedArrow->SetMaxAlpha(0.5f);
            }
void PinsExample::CreateExamplePins()
{
	// Get the repository of all currently active Pins.
	Eegeo::Pins::PinRepository& pinRepository = m_pPinsModule->GetRepository();

	// Create test pins and add them to the repository.
	Eegeo::Pins::TPinId pin0Id = 0;
	Eegeo::Space::LatLong pin0Location = Eegeo::Space::LatLong::FromDegrees(37.7858,-122.401);
	int pin0Icon = 0;
	Eegeo::Pins::Pin* pPin0 = Eegeo_NEW(Eegeo::Pins::Pin)(pin0Id, pin0Location, 0, pin0Icon, &m_pin0UserData);
	pinRepository.AddPin(*pPin0);

	// Save this pin so that we can add and remove it in AddRemovePin0()
	m_pPin0 = pPin0;

	Eegeo::Pins::TPinId pin1Id = 1;
	Eegeo::Space::LatLong pin1Location = Eegeo::Space::LatLong::FromDegrees(37.78547,-122.40259);
	int pin1Icon = 1;
	Eegeo::Pins::Pin* pPin1 = Eegeo_NEW(Eegeo::Pins::Pin)(pin1Id, pin1Location, 0, pin1Icon, &m_pin1UserData);
	pinRepository.AddPin(*pPin1);

	Eegeo::Pins::TPinId pin2Id = 2;
	Eegeo::Space::LatLong pin2Location = Eegeo::Space::LatLong::FromDegrees(37.78547,-122.402);
	int pin2Icon = 2;
	Eegeo::Pins::Pin* pPin2 = Eegeo_NEW(Eegeo::Pins::Pin)(pin2Id, pin2Location, 0, pin2Icon, &m_pin2UserData);
	pinRepository.AddPin(*pPin2);

	Eegeo::Pins::TPinId pin3Id = 3;
	Eegeo::Space::LatLong pin3Location = Eegeo::Space::LatLong::FromDegrees(37.78547,-122.403);
	int pin3Icon = 3;
	Eegeo::Pins::Pin* pPin3 = Eegeo_NEW(Eegeo::Pins::Pin)(pin3Id, pin3Location, 30, pin3Icon, &m_pin3UserData);
	pinRepository.AddPin(*pPin3);
}
            AboutPageMenuModule::AboutPageMenuModule(Menu::View::IMenuViewModel& menuViewModel,
                                                   AboutPage::View::IAboutPageViewModel& aboutPageViewModel)
            {

                m_pAboutPageMenuModel = Eegeo_NEW(Menu::View::MenuModel)();
                m_pAboutPageMenuOptionsModel = Eegeo_NEW(Menu::View::MenuOptionsModel)(*m_pAboutPageMenuModel);
                m_pAboutPageMenuOptionsModel->AddItem("About", "About", "", "", Eegeo_NEW(View::AboutPageMenuOption)(menuViewModel, aboutPageViewModel));
            }
    void PinOverModelExample::Start()
    {
        pModel = Eegeo::Model::CreateFromPODFile("Test_ROBOT_ARM.pod", fileIO, renderContext.GetGLState(), &textureRequestor, "");
        Eegeo_ASSERT(pModel->GetRootNode());

        m_pMyModelRenderable = Eegeo_NEW (MyModelRenderable)(*pModel, renderContext, globalFogging, nullMat);
        m_pMyRenderableFilter = Eegeo_NEW (MyRenderableFilter)(*m_pMyModelRenderable);
        renderableFilters.AddRenderableFilter(m_pMyRenderableFilter);
    }
void PinOverModelExample::Start()
{
	m_pModel = Eegeo::Model::CreateFromPODFile("pin_over_model_example/Test_ROBOT_ARM.pod", m_fileIO, m_renderContext.GetGLState(), &m_textureRequestor, "pin_over_model_example/");
	Eegeo_ASSERT(m_pModel->GetRootNode());

	m_pMyModelRenderable = Eegeo_NEW (MyModelRenderable)(*m_pModel, m_renderContext, m_globalFogging, m_nullMat);
	m_pMyRenderableFilter = Eegeo_NEW (MyRenderableFilter)(*m_pMyModelRenderable);
	m_renderableFilters.AddRenderableFilter(m_pMyRenderableFilter);
}
            ModalityModule::ModalityModule(ExampleAppMessaging::TMessageBus& messageBus,
                                           const std::vector<OpenableControl::View::IOpenableControlViewModel*>& viewModels)
            {
                m_pModel = Eegeo_NEW(ModalityModel)();

                m_pController = Eegeo_NEW(ModalityController)(*m_pModel,
                                viewModels);

                m_pModalityObserver = Eegeo_NEW(ModalityObserver)(*m_pModel, messageBus);
            }
 DecartaSearchServiceModule::DecartaSearchServiceModule(Eegeo::Web::IWebLoadRequestFactory& webLoadRequestFactory,
                                                        Eegeo::Helpers::UrlHelpers::IUrlEncoder& urlEncoder)
 {
     m_pSearchResultParser = Eegeo_NEW(Decarta::DecartaSearchJsonParser);
     
     m_pSearchService = Eegeo_NEW(Decarta::DecartaSearchService)(ExampleApp::DecartaApiKey,
                                                                 *m_pSearchResultParser,
                                                                 urlEncoder,
                                                                 webLoadRequestFactory);
 }
 TwitterFeedService::TwitterFeedService(Eegeo::Web::IWebLoadRequestFactory& webLoadRequestFactory)
 : m_accessToken("")
 , m_webLoadRequestFactory(webLoadRequestFactory)
 , m_pCurrentAuthRequest(NULL)
 , m_pCurrentTimeLineRequest(NULL)
 , m_pAuthCallback(Eegeo_NEW(Eegeo::Web::TWebLoadRequestCompletionCallback<TwitterFeedService>)(this, &TwitterFeedService::HandleAuthResponse))
 , m_pTimeLineCallback(Eegeo_NEW(Eegeo::Web::TWebLoadRequestCompletionCallback<TwitterFeedService>)(this, &TwitterFeedService::HandleTimeLineResponse))
 , m_currentServiceState(NOT_STARTED)
 {
     
 }
            ModalBackgroundViewModule::ModalBackgroundViewModule(
                AndroidNativeState& nativeState,
                Modality::View::IModalityModel& modalityModel,
                ExampleAppMessaging::TMessageBus& messageBus
            )
            {
                ASSERT_UI_THREAD

                m_pView = Eegeo_NEW(ModalBackgroundAggregateView)(nativeState, messageBus);
                m_pController = Eegeo_NEW(Modality::View::ModalBackgroundController)(*m_pView, modalityModel);
            }
CompassViewModule::CompassViewModule(
    WindowsNativeState& nativeState,
    ICompassViewModel& viewModel,
    ExampleAppMessaging::TMessageBus& messageBus
)
{
    m_pView = Eegeo_NEW(CompassView)(nativeState);
    m_pController = Eegeo_NEW(CompassController)(
                        *m_pView,
                        viewModel,
                        messageBus);
}
			GpsMarkerTutorialViewModule::GpsMarkerTutorialViewModule(WindowsNativeState& nativeState,
                                                                     ExampleAppMessaging::TMessageBus& messageBus,
                                                                     const GpsMarker::SdkModel::GpsMarkerModel& gpsMarkerModel,
                                                                     Eegeo::Rendering::EnvironmentFlatteningService& environmentFlatteningService)
			{
				m_pView = Eegeo_NEW(GpsMarkerTutorialView)();

				m_pController = Eegeo_NEW(GpsMarkerTutorialController)(*m_pView,
                                                                       messageBus,
                                                                       gpsMarkerModel,
                                                                       environmentFlatteningService);
			}
            TagSearchViewModule* TagSearchViewModule::Create(
                    Menu::View::IMenuOptionsModel& menuOptionsModel,
                    Menu::View::IMenuViewModel& menuViewModel,
                    ExampleAppMessaging::TMessageBus& messageBus,
                    const Menu::View::IMenuReactionModel& menuReaction)
            {
                auto* pController = Eegeo_NEW(TagSearch::View::TagSearchSectionController)(
                        menuOptionsModel,
                        menuViewModel,
                        messageBus,
                        menuReaction);

                return Eegeo_NEW(TagSearchViewModule)(pController);
            }
 InitialExperienceSearchResultAttractModeModule::InitialExperienceSearchResultAttractModeModule(PersistentSettings::IPersistentSettingsModel& persistentSettings,
                                                                                                Menu::View::IMenuViewModel& searchMenuViewModelControl,
                                                                                                SearchResultMenu::View::ISearchResultMenuViewModel& searchResultMenuViewModel,
                                                                                                ExampleAppMessaging::TMessageBus& messageBus)
 : m_pInitialExperienceSearchResultAttractModeModel(NULL)
 , m_pInitialExperienceSearchResultAttractModeViewController(NULL)
 {
     
     m_pInitialExperienceSearchResultAttractModeModel = Eegeo_NEW(SdkModel::InitialExperienceSearchResultAttractModeModel)(persistentSettings,
                                                                                           messageBus);
     
     m_pInitialExperienceSearchResultAttractModeViewController = Eegeo_NEW(View::InitialExperienceSearchResultAttractModeViewController)(searchMenuViewModelControl,
                                                                                           searchResultMenuViewModel,                   messageBus);
 }
	PinsWithAttachedJavaUIExample::PinsWithAttachedJavaUIExample(
							Eegeo::EegeoWorld& world,
							AndroidNativeState& nativeState,
							Eegeo::Rendering::RenderContext& renderContext,
                            Eegeo::Helpers::ITextureFileLoader& textureLoader,
                            Eegeo::Rendering::GlBufferPool& glBufferPool,
                            Eegeo::Rendering::Shaders::ShaderIdGenerator& shaderIdGenerator,
                            Eegeo::Rendering::Materials::MaterialIdGenerator& materialIdGenerator,
                            Eegeo::Rendering::VertexLayouts::VertexBindingPool& vertexBindingPool,
                            Eegeo::Rendering::VertexLayouts::VertexLayoutPool& vertexLayoutPool,
                            Eegeo::Rendering::RenderableFilters& renderableFilters,
                            const Eegeo::Camera::ICameraProvider& cameraProvider,
                            Eegeo::Resources::Terrain::Heights::TerrainHeightProvider& terrainHeightProvider,
                            Eegeo::Rendering::EnvironmentFlatteningService& environmentFlatteningService
                            )
	: m_nativeState(nativeState)
	, m_renderContext(renderContext)
	, m_world(world)
    , m_pinUserData("Pin User Data")
    {
        textureLoader.LoadTexture(m_pinIconsTexture, "PinIconTexturePage.png", true);
        Eegeo_ASSERT(m_pinIconsTexture.textureId != 0);

        int numberOfTilesAlongEachAxisOfTexturePage = 2;
        m_pPinIconsTexturePageLayout = Eegeo_NEW(Eegeo::Rendering::RegularTexturePageLayout)(
        		numberOfTilesAlongEachAxisOfTexturePage);

        // The following values specify the size and shape of the Pins within the 3D world.
        int spriteWidthInMetres = 100;
        int spriteHeightInMetres = 100;

        m_pPinsModule = Eegeo_NEW(Eegeo::Pins::PinsModule)(
        		m_pinIconsTexture.textureId,
        		*m_pPinIconsTexturePageLayout,
        		glBufferPool,
				shaderIdGenerator,
				materialIdGenerator,
				vertexBindingPool,
				vertexLayoutPool,
				renderableFilters,
				cameraProvider,
				terrainHeightProvider,
				spriteWidthInMetres,
				spriteHeightInMetres,
				Eegeo::Rendering::LayerIds::PlaceNames,
				environmentFlatteningService);

        CreateExamplePins();
    }
 InteriorExplorerState::InteriorExplorerState(AppCamera::SdkModel::IAppCameraController& cameraController,
                                              Eegeo::Resources::Interiors::InteriorSelectionModel& interiorSelectionModel,
                                              Eegeo::Resources::Interiors::InteriorInteractionModel& interiorInteractionModel,
                                              int interiorCameraHandle,
                                              Tours::SdkModel::ITourService& tourService,
                                              Eegeo::Streaming::CameraFrustumStreamingVolume& cameraFrustumStreamingVolume,
                                              InteriorsExplorer::SdkModel::InteriorVisibilityUpdater& interiorVisibilityUpdater,
                                              InteriorsExplorer::SdkModel::InteriorsExplorerModel& interiorsExplorerModel,
                                              InteriorsExplorer::SdkModel::InteriorExplorerUserInteractionModel& interiorExplorerUserInteractionModel,
                                              AppModes::SdkModel::IAppModeModel& appModeModel,
                                              Eegeo::Camera::GlobeCamera::GpsGlobeCameraController& worldCameraController,
                                              Eegeo::Resources::Interiors::InteriorsCameraController& interiorsCameraController,
                                              Eegeo::UI::NativeUIFactories& nativeUIFactories,
                                              MyPinCreation::SdkModel::IMyPinCreationModel& myPinCreationModel)
 : m_tourService(tourService)
 , m_tourStartedCallback(this, &InteriorExplorerState::OnTourStarted)
 , m_interiorExplorerUserInteractionModel(interiorExplorerUserInteractionModel)
 , m_appModeModel(appModeModel)
 , m_worldCameraController(worldCameraController)
 , m_interiorsCameraController(interiorsCameraController)
 , m_nativeUIFactories(nativeUIFactories)
 , m_failAlertHandler(this, &InteriorExplorerState::OnFailAlertBoxDismissed)
 , m_myPinCreationModel(myPinCreationModel)
 , m_lastEntryAttemptSuccessful(false)
 {
     
     m_subStates.push_back(Eegeo_NEW(InteriorsExplorer::SdkModel::States::InteriorExplorerSetupState)(*this,
                                                                                                      cameraController,
                                                                                                      interiorCameraHandle));
     
     m_subStates.push_back(Eegeo_NEW(InteriorsExplorer::SdkModel::States::InteriorExplorerStreamState)(*this,
                                                                                                       interiorInteractionModel,
                                                                                                       cameraFrustumStreamingVolume,
                                                                                                       interiorVisibilityUpdater));
     
     m_subStates.push_back(Eegeo_NEW(InteriorsExplorer::SdkModel::States::InteriorExplorerViewingState)(*this,
                                                                                                        interiorsExplorerModel,
                                                                                                        interiorExplorerUserInteractionModel,
                                                                                                        cameraFrustumStreamingVolume));
     
     m_subStates.push_back(Eegeo_NEW(InteriorsExplorer::SdkModel::States::InteriorExplorerExitingState)(*this,
                                                                                                        interiorSelectionModel,
                                                                                                        cameraFrustumStreamingVolume,
                                                                                                        interiorVisibilityUpdater,
                                                                                                        interiorsExplorerModel
                                                                                                        ));
     
     m_pSubStateMachine = Eegeo_NEW(Helpers::StateMachine)(m_subStates);
 }
            MyPinCreationDetailsViewModule::MyPinCreationDetailsViewModule(
                WindowsNativeState& nativeState,
                MyPinCreationDetails::View::IMyPinCreationDetailsViewModel& viewModel,
                ExampleAppMessaging::TMessageBus& messageBus,
                Metrics::IMetricsService& metricsService
            )
            {
                m_pView = Eegeo_NEW(MyPinCreationDetailsView)(nativeState);

                m_pController = Eegeo_NEW(MyPinCreationDetailsController)(*m_pView,
                                viewModel,
                                messageBus,
                                metricsService
                                                                         );
            }
            MyPinCreationViewModule::MyPinCreationViewModule(
                AndroidNativeState& nativeState,
                IMyPinCreationInitiationViewModel& initiationViewModel,
                IMyPinCreationConfirmationViewModel& confirmationViewModel,
                MyPinCreationDetails::View::IMyPinCreationDetailsViewModel& detailsViewModel,
                ExampleAppMessaging::TMessageBus& messageBus,
                Metrics::IMetricsService& metricsService
            )
            {
                m_pInitiationView = Eegeo_NEW(MyPinCreationInitiationView)(nativeState);
                m_pInitiationController = Eegeo_NEW(MyPinCreationInitiationController)(initiationViewModel, *m_pInitiationView, confirmationViewModel, messageBus, metricsService);

                m_pConfirmationView = Eegeo_NEW(MyPinCreationConfirmationView)(nativeState);
                m_pConfirmationController = Eegeo_NEW(MyPinCreationConfirmationController)(confirmationViewModel, *m_pConfirmationView, detailsViewModel, messageBus, metricsService);
            }
            WorldPinItemModel* WorldPinsService::AddPin(IWorldPinSelectionHandler* pSelectionHandler,
                                                        IWorldPinVisibilityStateChangedHandler* pVisibilityStateChangedHandler,
                                                        const WorldPinFocusData& worldPinFocusData,
                                                        const Eegeo::Space::LatLong& location,
                                                        int iconIndex)
            {
                
                Eegeo::Pins::Pin* pPin = m_worldPinsFactory.CreatePin(location, iconIndex);

                m_pinRepository.AddPin(*pPin);

                Eegeo::Pins::TPinId pinId = pPin->GetId();

                TPinToSelectionHandlerMapIt pinToSelectionHandlerMapIt = m_pinsToSelectionHandlers.find(pinId);
                Eegeo_ASSERT(pinToSelectionHandlerMapIt == m_pinsToSelectionHandlers.end(), "Attempting to add same pin ID %d twice.\n", pinId);
                m_pinsToSelectionHandlers[pinId] = pSelectionHandler;
                
                TPinToVisiblityHandlerMapIt pinToVisiblityHandlerMapIt = m_pinsToVisbilityChangedHandlers.find(pinId);
                Eegeo_ASSERT(pinToVisiblityHandlerMapIt == m_pinsToVisbilityChangedHandlers.end(), "Attempting to add same pin ID %d twice.\n", pinId);
                m_pinsToVisbilityChangedHandlers[pinId] = pVisibilityStateChangedHandler;

                WorldPinItemModel* model = Eegeo_NEW(WorldPinItemModel)(pinId,
                                                                        pSelectionHandler,
                                                                        pVisibilityStateChangedHandler,
                                                                        worldPinFocusData);
                m_worldPinsRepository.AddItem(model);

                UpdatePinScale(*model, model->TransitionStateValue());

                return model;
            }
            void SearchQueryPerformer::HandleSearchResultsResponseReceived(const SearchQuery& query,
                    const std::vector<SearchResultModel>& results)
            {
                // Ideally we should keep merge the new results into the old result set in a stable way, so that the
                // result list doesn't jumble up when we move about and perform new searches.

                std::map<SearchResultModel, size_t> currentRepoHash;
                std::set<size_t> retainedResultIndices;
                std::vector<SearchResultModel*> newResultTemporaryStorage;
                const int topIndexBeforeAddingNewResult = static_cast<int>(m_searchResultsRepository.GetItemCount() - 1);

                // First of all lets map the contents of the results repo so we can easily look results up later.
                // Map the result to its index.
                for(size_t i = 0; i < m_searchResultsRepository.GetItemCount(); ++ i)
                {
                    SearchResultModel* pItem = m_searchResultsRepository.GetItemAtIndex(i);
                    currentRepoHash.insert(std::make_pair(*pItem, i));
                }

                // For the new results, check if we already have the result using the map. If so, we flag the results
                // index as 'retained'. This will be used later when removing old results. If we have not seen the result
                // before, add it to a new temporary vector.
                for(std::vector<SearchResultModel>::const_iterator it = results.begin();
                        it != results.end();
                        ++ it)
                {
                    std::map<SearchResultModel, size_t>::iterator mapIt = currentRepoHash.find(*it);

                    if(mapIt == currentRepoHash.end())
                    {
                        SearchResultModel* pItem = Eegeo_NEW(SearchResultModel)(*it);

                        newResultTemporaryStorage.push_back(pItem);
                    }
                    else
                    {
                        retainedResultIndices.insert(mapIt->second);
                    }
                }

                // Walk backwards over the repository removing old results which are not retained, by inspection of
                // the retained indices.
                for(int i = topIndexBeforeAddingNewResult; i >= 0; --i)
                {
                    if(retainedResultIndices.find(i) == retainedResultIndices.end())
                    {
                        SearchResultModel* pItem = m_searchResultsRepository.GetItemAtIndex(i);
                        m_searchResultsRepository.RemoveItem(pItem);
                        Eegeo_DELETE pItem;
                    }
                }

                // Add the new results on the end after removing the old results.
                for(std::vector<SearchResultModel*>::const_iterator it = newResultTemporaryStorage.begin();
                        it != newResultTemporaryStorage.end();
                        ++ it)
                {
                    m_searchResultsRepository.AddItem(*it);
                }
            }
            SearchResultPinBoundObject* SearchResultPinBoundObject::FromSerializedData(MyPinModel::TPinIdType pinId,
                                                                                       const std::string& pinMetadataJson,
                                                                                       const std::string& pinIconKey,
                                                                                       MyPinsFileIO& myPinsFileIO,
                                                                                       Search::SdkModel::MyPins::IMyPinsSearchResultRefreshService& myPinsSearchResultRefreshService,
                                                                                       ExampleAppMessaging::TMessageBus& messageBus,
                                                                                       ExampleAppMessaging::TSdkModelDomainEventBus& sdkModelDomainEventBus,
                                                                                       ExampleApp::MyPins::SdkModel::IMyPinsService& myPinsService)
            {
                Eegeo_ASSERT(!pinIconKey.empty());

                Search::SdkModel::SearchResultModel searchResultModel;
                
                if(!Search::SdkModel::TryDeserializeFromJson(pinMetadataJson, searchResultModel))
                {
                    return NULL;
                }

                return Eegeo_NEW(SearchResultPinBoundObject)(pinId,
                                                             searchResultModel,
                                                             pinIconKey,
                                                             myPinsFileIO,
                                                             myPinsSearchResultRefreshService,
                                                             messageBus,
                                                             sdkModelDomainEventBus,
                                                             myPinsService);
            }
            void SearchResultSectionController::OnSearchQueryResponseReceivedMessage(const Search::SearchQueryResponseReceivedMessage& message)
            {
                for(int i = 0; i < m_lastAddedResults.size(); ++i)
                {
                    const Search::SdkModel::SearchResultModel& model(m_lastAddedResults[i]);
                    m_menuOptions.RemoveItem(model.GetIdentifier());
                }
                
                m_lastAddedResults = message.GetResults();
                
//                const std::vector<Search::SdkModel::SearchResultModel>& unorderedResults = message.GetResults();
                
                OrderWrapper orderWrapper(m_order);
                std::stable_sort(m_lastAddedResults.begin(), m_lastAddedResults.end(), orderWrapper);
                
                for(int i = 0; i < m_lastAddedResults.size(); ++i)
                {
                    const Search::SdkModel::SearchResultModel& model(m_lastAddedResults[i]);
                    m_menuOptions.AddItem(model.GetIdentifier(),
                                          model.GetTitle(),
                                          model.GetSubtitle(),
                                          model.GetCategory(),
                                          Eegeo_NEW(SearchResultItemModel)(model.GetTitle(),
                                                                           model.GetLocation().ToECEF(),
                                                                           model.IsInterior(),
                                                                           model.GetBuildingId(),
                                                                           model.GetFloor(),
                                                                           m_searchMenuViewModel,
                                                                           m_messageBus,
                                                                           m_menuReaction));
                    
                }
            }
            void InitialExperienceModuleBase::InitialiseWithApplicationModels(WorldAreaLoader::SdkModel::IWorldAreaLoaderModel &worldAreaLoaderModel,
                                                                              Menu::View::IMenuViewModel& searchMenuViewModelControl,
                                                                              SearchResultMenu::View::ISearchResultMenuViewModel& searchResultMenuViewModel)
            {
                Eegeo_ASSERT(m_pInitialExperienceModel == NULL, "Cannot call InitialExperienceModule::InitialiseWithApplicationModels twice.\n");

                std::vector<IInitialExperienceStep*> steps = CreateSteps(worldAreaLoaderModel,
                                                                         searchMenuViewModelControl,
                                                                         searchResultMenuViewModel);

                const int lastCameraLockedStep = 1;
                
                m_pInitialExperienceModel = Eegeo_NEW(InitialExperienceModel)(steps, lastCameraLockedStep);

                m_pInitialExperienceController = Eegeo_NEW(InitialExperienceController)(*m_pInitialExperienceModel);
            }
            SearchResultMenuModule::SearchResultMenuModule(Search::SdkModel::ISearchResultRepository& searchResultRepository,
                    Search::SdkModel::ISearchQueryPerformer& searchQueryPerformer,
                    Eegeo::Helpers::IIdentityProvider& identityProvider,
                    CameraTransitions::SdkModel::ICameraTransitionController& cameraTransitionController,
                    Reaction::View::IReactionControllerModel& reactionControllerModel,
                    ExampleAppMessaging::TMessageBus& messageBus)
            {
                m_pModel = Eegeo_NEW(Menu::View::MenuModel)();

                m_pMenuOptionsModel = Eegeo_NEW(Menu::View::MenuOptionsModel)(*m_pModel);

                m_pViewModel = Eegeo_NEW(View::SearchResultMenuViewModel)(*m_pModel,
                               false,
                               identityProvider.GetNextIdentity(),
                               reactionControllerModel);

                m_pMenuSection = Eegeo_NEW(Menu::View::MenuSectionViewModel)("Search", "search", *m_pModel, false);
                m_pViewModel->AddSection(*m_pMenuSection);

                m_pSearchResultRepositoryObserver = Eegeo_NEW(View::SearchResultRepositoryObserver)(
                                                        searchResultRepository,
                                                        messageBus
                                                    );

                m_pSearchResultMenuItemSelectedMessageHandler = Eegeo_NEW(SearchResultMenuItemSelectedMessageHandler)(
                            cameraTransitionController,
                            messageBus
                        );

                m_pSearchResultAddRemoveHandler = Eegeo_NEW(View::SearchResultAddRemoveHandler)(
                                                      *m_pMenuOptionsModel,
                                                      *m_pViewModel,
                                                      messageBus
                                                  );

                m_pSearchResultMenuSearchQueryPerformedMessageHandler = Eegeo_NEW(View::SearchResultMenuSearchQueryPerformedMessageHandler)(
                            *m_pViewModel,
                            messageBus
                        );

                m_pSearchResultMenuSearchQueryRemovedMessageHandler = Eegeo_NEW(View::SearchResultMenuSearchQueryRemovedMessageHandler)(
                            *m_pViewModel,
                            messageBus
                        );

                m_pSearchResultViewClearedObserver = Eegeo_NEW(SearchResultViewClearedObserver)(searchQueryPerformer, messageBus);
            }
 void SecondaryMenuModule::AddMenuSection(const std::string& name,
                                          Menu::View::IMenuModel& menuModel,
                                          bool isExpandable)
 {
     Menu::View::MenuSectionViewModel* pMenuSection = Eegeo_NEW(Menu::View::MenuSectionViewModel)(name, "", menuModel, isExpandable);
     m_pViewModel->AddSection(*pMenuSection);
     m_sections.push_back(pMenuSection);
 }
 IGeoNamesSearchQuery* GeoNamesSearchQueryFactory::CreateGeoNamesSearchForQuery(const SdkModel::SearchQuery& query,
                                                                                Eegeo::Helpers::ICallback0& completionCallback)
 {
     return Eegeo_NEW(GeoNamesSearchQuery)(m_webRequestFactory,
                                           m_urlEncoder,
                                           query,
                                           completionCallback);
 }
            std::vector<IInitialExperienceStep*> AndroidInitialExperienceModule::CreateSteps(WorldAreaLoader::SdkModel::IWorldAreaLoaderModel& worldAreaLoaderModel)
            {
                std::vector<IInitialExperienceStep*> steps;

                IInitialExperienceStep* pIntroStep = Eegeo_NEW(InitialExperienceIntroStep)(m_messageBus, GetPersistentSettings());
                steps.push_back(pIntroStep);

                IInitialExperienceStep* pWorldAreaLoaderStep = Eegeo_NEW(PreLoad::SdkModel::AndroidInitialExperiencePreLoadModel)(
                            m_nativeState,
                            worldAreaLoaderModel,
                            GetPersistentSettings()
                        );

                steps.push_back(pWorldAreaLoaderStep);

                return steps;
            }
            MyPinCreationDetailsViewModule::MyPinCreationDetailsViewModule(
                AndroidNativeState& nativeState,
                MyPinCreationDetails::View::IMyPinCreationDetailsViewModel& viewModel,
                Eegeo::Web::IConnectivityService& connectivityService,
                ExampleAppMessaging::TMessageBus& messageBus,
                Metrics::IMetricsService& metricsService
            )
            {
                m_pView = Eegeo_NEW(MyPinCreationDetailsView)(nativeState);

                m_pController = Eegeo_NEW(MyPinCreationDetailsController)(*m_pView,
                                viewModel,
                                connectivityService,
                                messageBus,
                                metricsService
                                                                         );
            }