bool PinsWithAttachedJavaUIExample::Event_TouchTap(const AppInterface::TapData& data)
    {
        Eegeo::v2 screenTapPoint = Eegeo::v2(data.point.GetX(), data.point.GetY());

        Eegeo_TTY("Searching for Pins intersecting tap point %d,%d...", (int) screenTapPoint.GetX(), (int) screenTapPoint.GetY());

        Eegeo::Pins::PinController& pinController = m_pPinsModule->GetController();
        std::vector<Eegeo::Pins::Pin*> intersectingPinsClosestToCameraFirst;
        if(pinController.TryGetPinsIntersectingScreenPoint(screenTapPoint, intersectingPinsClosestToCameraFirst))
        {
            Eegeo_TTY("found %ld :\n", intersectingPinsClosestToCameraFirst.size());

            for(std::vector<Eegeo::Pins::Pin*>::const_iterator it = intersectingPinsClosestToCameraFirst.begin(); it != intersectingPinsClosestToCameraFirst.end(); ++it)
            {
                Eegeo::Pins::Pin* pPin = *it;

                Eegeo_TTY("\tId=%d, User Data='%s'\n", pPin->GetId(), ((std::string*) pPin->GetUserData())->c_str());
            }

            return true;
        }
        else
        {
            Eegeo_TTY("none found.\n");
            return false;
        }
    }
            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 WorldPinsService::UpdatePinScale(const WorldPinItemModel& pinItemModel, float scale)
            {
                Eegeo::Pins::Pin* pPin = m_pinRepository.GetPinById(pinItemModel.Id());
                Eegeo_ASSERT(pPin != NULL);

                float scaleWithTerrainHeight = pPin->HasTerrainHeight() ? scale : 0.f;
                m_pinController.SetScaleForPin(*pPin, scaleWithTerrainHeight);
            }
            void WorldPinsService::GetPinEcefAndScreenLocations(const WorldPinItemModel& pinItemModel,
                    Eegeo::dv3& ecefLocation,
                    Eegeo::v2& screenLocation) const
            {
                Eegeo::Pins::Pin* pPin = m_pinRepository.GetPinById(pinItemModel.Id());
                Eegeo_ASSERT(pPin != NULL);

                ecefLocation = m_environmentFlatteningService.GetScaledPointEcef(pPin->GetEcefPosition(),
                               m_environmentFlatteningService.GetCurrentScale());

                Eegeo::Geometry::Bounds2D outScreenBounds = Eegeo::Geometry::Bounds2D::Empty();
                m_pinController.GetScreenBoundsForPin(*pPin, outScreenBounds);
                screenLocation = outScreenBounds.center();
            }
            bool WorldPinsService::HandleTouchTap(const Eegeo::v2& screenTapPoint)
            {
                std::vector<Eegeo::Pins::Pin*> intersectingPinsClosestToCameraFirst;

                if(m_pinController.TryGetPinsIntersectingScreenPoint(screenTapPoint, intersectingPinsClosestToCameraFirst))
                {
                    Eegeo_ASSERT(intersectingPinsClosestToCameraFirst.size() > 0);
                    Eegeo::Pins::Pin* pSelectedPin = intersectingPinsClosestToCameraFirst[0];
                    Eegeo_ASSERT(pSelectedPin != NULL);
                    TPinToSelectionHandlerMapIt pinToSelectionHandlerMapIt = m_pinsToSelectionHandlers.find(pSelectedPin->GetId());
                    Eegeo_ASSERT(pinToSelectionHandlerMapIt != m_pinsToSelectionHandlers.end(),
                                 "Selected pin with unknown ID %d.\n", pSelectedPin->GetId());
                    IWorldPinSelectionHandler& selectionHandler = *pinToSelectionHandlerMapIt->second;
                    selectionHandler.SelectPin();
                    return true;
                }

                return false;
            }