--- /dev/null
+package com.intellij.stats.personalization
+
+import com.intellij.codeInsight.lookup.LookupElement
+
+/**
+ * @author Vitaliy.Bibaev
+ */
+interface UserFactor {
+ val id: String
+
+ fun store(element: LookupElement)
+ fun extract(element: LookupElement): Comparable<Nothing>
+}
--- /dev/null
+package com.intellij.stats.personalization
+
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.project.Project
+import com.intellij.stats.personalization.impl.ApplicationUserFactorStorage
+import com.intellij.stats.personalization.impl.ProjectUserFactorStorage
+
+/**
+ * @author Vitaliy.Bibaev
+ */
+interface UserFactorStorage {
+ companion object {
+ fun getInstance(): UserFactorStorage =
+ ApplicationManager.getApplication().getComponent(ApplicationUserFactorStorage::class.java)
+
+ fun getInstance(project: Project): UserFactorStorage = project.getComponent(ProjectUserFactorStorage::class.java)
+ }
+
+ fun getBoolean(factorId: String): Boolean?
+ fun getDouble(factorId: String): Double?
+ fun getString(factorId: String): String?
+
+ fun setBoolean(factorId: String, value: Boolean)
+ fun setDouble(factorId: String, value: Double)
+ fun setString(factorId: String, value: String)
+}
\ No newline at end of file
--- /dev/null
+package com.intellij.stats.personalization.impl
+
+import com.intellij.openapi.components.ApplicationComponent
+import com.intellij.openapi.components.State
+import com.intellij.openapi.components.Storage
+
+/**
+ * @author Vitaliy.Bibaev
+ */
+@State(name = "ApplicationUserFactors", storages = arrayOf(Storage("completion.factors.user.xml")))
+class ApplicationUserFactorStorage : ApplicationComponent, UserFactorStorageBase()
\ No newline at end of file
--- /dev/null
+package com.intellij.stats.personalization.impl
+
+import com.intellij.openapi.components.ProjectComponent
+import com.intellij.openapi.components.State
+import com.intellij.openapi.components.Storage
+
+/**
+ * @author Vitaliy.Bibaev
+ */
+@State(name = "ProjectUserFactors", storages = arrayOf(Storage("completion.factors.user.xml")))
+class ProjectUserFactorStorage : ProjectComponent, UserFactorStorageBase()
\ No newline at end of file
--- /dev/null
+package com.intellij.stats.personalization.impl
+
+import com.intellij.openapi.components.PersistentStateComponent
+import com.intellij.stats.personalization.UserFactorStorage
+import com.intellij.util.xmlb.annotations.MapAnnotation
+import java.util.HashMap
+
+abstract class UserFactorStorageBase
+ : UserFactorStorage, PersistentStateComponent<UserFactorStorageBase.CollectorState> {
+
+ private var state = CollectorState()
+
+ override fun getBoolean(factorId: String): Boolean? = state.booleanFactors[factorId]
+
+ override fun getString(factorId: String): String? = state.stringFactors[factorId]
+
+ override fun getDouble(factorId: String): Double? = state.doubleFactors[factorId]
+
+ override fun setBoolean(factorId: String, value: Boolean) = state.booleanFactors.update(factorId, value)
+
+ override fun setDouble(factorId: String, value: Double) = state.doubleFactors.update(factorId, value)
+
+ override fun setString(factorId: String, value: String) = state.stringFactors.update(factorId, value)
+
+ private fun <T> MutableMap<String, T>.update(factorId: String, value: T) {
+ this[factorId] = value
+ }
+
+ override fun getState(): CollectorState = state
+
+ override fun loadState(newState: CollectorState) {
+ state = newState
+ }
+
+ class CollectorState {
+ @MapAnnotation(surroundKeyWithTag = false, keyAttributeName = "name", sortBeforeSave = true)
+ var booleanFactors: MutableMap<String, Boolean> = HashMap()
+
+ @MapAnnotation(surroundKeyWithTag = false, keyAttributeName = "name", sortBeforeSave = true)
+ var doubleFactors: MutableMap<String, Double> = HashMap()
+
+ @MapAnnotation(surroundKeyWithTag = false, keyAttributeName = "name", sortBeforeSave = true)
+ var stringFactors: MutableMap<String, String> = HashMap()
+ }
+}
\ No newline at end of file