/**
  * @param type Type of the expression leading upto the 'nav' operator
  * @param navOffset Offset of the nav operator (either ']' or '.'
  * @param offset Offset of the cursor where CA was requested.
  * @return
  */
 private Collection<ICompletionProposal> getNavigationProposals(
     IDocument doc, Type type, int navOffset, int offset) {
   try {
     char navOp = doc.getChar(navOffset);
     if (navOp == '.') {
       String prefix = doc.get(navOffset + 1, offset - (navOffset + 1));
       EnumCaseMode caseMode = caseMode(prefix);
       List<TypedProperty> objectProperties =
           typeUtil.getProperties(type, caseMode, BeanPropertyNameMode.HYPHENATED);
       // Note: properties editor itself deals with relaxed names. So it expects the properties
       // here to be returned in hyphenated form only.
       if (objectProperties != null && !objectProperties.isEmpty()) {
         ArrayList<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
         for (TypedProperty prop : objectProperties) {
           double score = FuzzyMatcher.matchScore(prefix, prop.getName());
           if (score != 0) {
             Type valueType = prop.getType();
             String postFix = propertyCompletionPostfix(valueType);
             DocumentEdits edits = new DocumentEdits(doc);
             edits.delete(navOffset + 1, offset);
             edits.insert(offset, prop.getName() + postFix);
             proposals.add(completionFactory.simpleProposal(prop.getName(), score, edits));
           }
         }
         return proposals;
       }
     } else {
       // TODO: other cases ']' or '[' ?
     }
   } catch (Exception e) {
     BootActivator.log(e);
   }
   return Collections.emptyList();
 }
 private Collection<ICompletionProposal> getNavigationProposals(IDocument doc, int offset) {
   String navPrefix = navigationPrefixFinder.getPrefix(doc, offset);
   try {
     if (navPrefix != null) {
       int navOffset =
           offset - navPrefix.length() - 1; // offset of 'nav' operator char (i.e. '.' or ']').
       navPrefix = fuzzySearchPrefix.getPrefix(doc, navOffset);
       if (navPrefix != null && !navPrefix.isEmpty()) {
         PropertyInfo prop = findLongestValidProperty(getIndex(), navPrefix);
         if (prop != null) {
           int regionStart = navOffset - navPrefix.length();
           PropertyNavigator navigator =
               new PropertyNavigator(doc, null, typeUtil, region(regionStart, navOffset));
           Type type =
               navigator.navigate(
                   regionStart + prop.getId().length(), TypeParser.parse(prop.getType()));
           if (type != null) {
             return getNavigationProposals(doc, type, navOffset, offset);
           }
         }
       }
     }
   } catch (Exception e) {
     BootActivator.log(e);
   }
   return Collections.emptyList();
 }
 @Override
 public void apply(IDocument document) {
   try {
     proposalApplier.apply(document);
   } catch (Exception e) {
     BootActivator.log(e);
   }
 }
 public Point getSelection(IDocument document) {
   try {
     return proposalApplier.getSelection(document);
   } catch (Exception e) {
     BootActivator.log(e);
     return null;
   }
 }
 @Override
 public Point getSelection(IDocument doc) {
   try {
     return applier.getSelection(doc);
   } catch (Exception e) {
     BootActivator.log(e);
   }
   return null;
 }
 private boolean hasMainMethod(IType t) {
   try {
     for (IMethod m : t.getMethods()) {
       if (m.isMainMethod()) {
         return true;
       }
     }
   } catch (Exception e) {
     BootActivator.log(e);
   }
   return false;
 }
 @Override
 public synchronized ExternalTypeDiscovery discoveryFor(IJavaProject project) {
   if (isApplicable(project)) {
     try {
       if (instance == null) {
         instance = new SpringBootTypeDiscovery();
       }
       return instance;
     } catch (Exception e) {
       BootActivator.log(e);
     }
   }
   return null;
 }
 /** Determine the value type for a give propertyName. */
 protected Type getValueType(String propertyName) {
   try {
     PropertyInfo prop = getIndex().get(propertyName);
     if (prop != null) {
       return TypeParser.parse(prop.getType());
     } else {
       prop = findLongestValidProperty(getIndex(), propertyName);
       if (prop != null) {
         Document doc = new Document(propertyName);
         PropertyNavigator navigator =
             new PropertyNavigator(doc, null, typeUtil, new Region(0, doc.getLength()));
         return navigator.navigate(prop.getId().length(), TypeParser.parse(prop.getType()));
       }
     }
   } catch (Exception e) {
     BootActivator.log(e);
   }
   return null;
 }
 @Override
 public void init(IWorkbench workbench) {
   IPreferenceStore store = BootActivator.getDefault().getPreferenceStore();
   store.setDefault(PREF_IGNORE_SILENT_EXIT, DEFAULT_PREF_IGNORE_SILENT_EXIT);
   setPreferenceStore(BootActivator.getDefault().getPreferenceStore());
 }