[
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n"
  },
  {
    "path": ".idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <resourceExtensions />\n    <wildcardResourcePatterns>\n      <entry name=\"!?*.java\" />\n      <entry name=\"!?*.form\" />\n      <entry name=\"!?*.class\" />\n      <entry name=\"!?*.groovy\" />\n      <entry name=\"!?*.scala\" />\n      <entry name=\"!?*.flex\" />\n      <entry name=\"!?*.kt\" />\n      <entry name=\"!?*.clj\" />\n      <entry name=\"!?*.aj\" />\n    </wildcardResourcePatterns>\n    <annotationProcessing>\n      <profile default=\"true\" name=\"Default\" enabled=\"false\">\n        <processorPath useClasspath=\"true\" />\n      </profile>\n    </annotationProcessing>\n  </component>\n</project>"
  },
  {
    "path": ".idea/copyright/profiles_settings.xml",
    "content": "<component name=\"CopyrightManager\">\n  <settings default=\"\" />\n</component>"
  },
  {
    "path": ".idea/encodings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\">\n    <file url=\"PROJECT\" charset=\"UTF-8\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/app\" />\n            <option value=\"$PROJECT_DIR$/library\" />\n          </set>\n        </option>\n        <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"EntryPointsManager\">\n    <entry_points version=\"2.0\" />\n  </component>\n  <component name=\"NullableNotNullManager\">\n    <option name=\"myDefaultNullable\" value=\"android.support.annotation.Nullable\" />\n    <option name=\"myDefaultNotNull\" value=\"android.support.annotation.NonNull\" />\n    <option name=\"myNullables\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.Nullable\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nullable\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.Nullable\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.Nullable\" />\n        </list>\n      </value>\n    </option>\n    <option name=\"myNotNulls\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.NotNull\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nonnull\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.NonNull\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.NonNull\" />\n        </list>\n      </value>\n    </option>\n  </component>\n  <component name=\"ProjectInspectionProfilesVisibleTreeState\">\n    <entry key=\"Project Default\">\n      <profile-state>\n        <expanded-state>\n          <State>\n            <id />\n          </State>\n        </expanded-state>\n        <selected-state>\n          <State>\n            <id>Android</id>\n          </State>\n        </selected-state>\n      </profile-state>\n    </entry>\n  </component>\n  <component name=\"ProjectLevelVcsManager\" settingsEditedManually=\"false\">\n    <OptionsSetting value=\"true\" id=\"Add\" />\n    <OptionsSetting value=\"true\" id=\"Remove\" />\n    <OptionsSetting value=\"true\" id=\"Checkout\" />\n    <OptionsSetting value=\"true\" id=\"Update\" />\n    <OptionsSetting value=\"true\" id=\"Status\" />\n    <OptionsSetting value=\"true\" id=\"Edit\" />\n    <ConfirmationsSetting value=\"0\" id=\"Add\" />\n    <ConfirmationsSetting value=\"0\" id=\"Remove\" />\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_7\" default=\"true\" assert-keyword=\"true\" jdk-15=\"true\" project-jdk-name=\"1.8\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n  <component name=\"SuppressionsComponent\">\n    <option name=\"suppComments\" value=\"[]\" />\n  </component>\n  <component name=\"masterDetails\">\n    <states>\n      <state key=\"Copyright.UI\">\n        <settings>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n      <state key=\"ScopeChooserConfigurable.UI\">\n        <settings>\n          <splitter-proportions>\n            <option name=\"proportions\">\n              <list>\n                <option value=\"0.2\" />\n              </list>\n            </option>\n          </splitter-proportions>\n        </settings>\n      </state>\n    </states>\n  </component>\n</project>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/DateTimeSeer.iml\" filepath=\"$PROJECT_DIR$/DateTimeSeer.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/app/app.iml\" filepath=\"$PROJECT_DIR$/app/app.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/library/library.iml\" filepath=\"$PROJECT_DIR$/library/library.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/qaplug_profiles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"AnalysisProjectProfileManager\">\n    <option name=\"PROJECT_PROFILE\" value=\"Project Default\" />\n    <option name=\"USE_PROJECT_LEVEL_SETTINGS\" value=\"false\" />\n    <scopes />\n    <profiles>\n      <profile version=\"1.0\" is_locked=\"false\">\n        <option name=\"myName\" value=\"Project Default\" />\n        <coding_rule class=\"AndroidCallSuperFirst\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"AndroidCallSuperLast\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"AndroidDoNotHardCodeSDCard\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicAvoidBranchingStatementAsLastInLoop\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicAvoidDecimalLiteralsInBigDecimalConstructor\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicAvoidMultipleUnaryOperators\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicAvoidThreadGroup\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"BasicAvoidUsingHardCodedIP\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicAvoidUsingOctalValues\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicBigIntegerInstantiation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicBooleanInstantiation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicBrokenNullCheck\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"BasicCheckResultSet\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicCheckSkipResult\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicClassCastExceptionWithToArray\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicCollapsibleIfStatements\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicDontCallThreadRun\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicDontUseFloatTypeForLoopIndices\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicDoubleCheckedLocking\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicExtendsObject\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicForLoopShouldBeWhileLoop\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSFDontNestJsfInJstlIteration\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSPIframeMissingSrcAttribute\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSPNoClassAttribute\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSPNoHtmlComments\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSPNoInlineStyleInformation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSPNoJspForward\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSPNoLongScripts\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJSPNoScriptlets\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicJumbledIncrementer\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicMisplacedNullCheck\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"BasicOverrideBothEqualsAndHashcode\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"BasicReturnFromFinallyBlock\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BasicUnconditionalIfStatement\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"BracesForLoopsMustUseBraces\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BracesIfElseStmtsMustUseBraces\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BracesIfStmtsMustUseBraces\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"BracesWhileLoopsMustUseBraces\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CloneImplementationCloneMethodMustImplementCloneable\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CloneImplementationCloneThrowsCloneNotSupportedException\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CloneImplementationProperCloneImplementation\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeCyclomaticComplexity\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeExcessiveClassLength\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeExcessiveMethodLength\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeExcessiveParameterList\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeExcessivePublicCount\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeNPathComplexity\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeNcssConstructorCount\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeNcssMethodCount\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeNcssTypeCount\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeTooManyFields\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CodeSizeTooManyMethods\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAssignmentInOperand\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAtLeastOneConstructor\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAvoidAccessibilityAlteration\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAvoidFinalLocalVariable\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAvoidLiteralsInIfCondition\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAvoidPrefixingMethodParameters\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAvoidUsingNativeCode\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAvoidUsingShortType\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialAvoidUsingVolatile\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialBooleanInversion\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialCallSuperInConstructor\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialDataflowAnomalyAnalysis\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialDefaultPackage\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialDoNotCallGarbageCollectionExplicitly\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"ControversialDontImportSun\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialNullAssignment\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialOneDeclarationPerLine\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialOnlyOneReturn\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialSuspiciousOctalEscape\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialUnnecessaryConstructor\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialUnnecessaryParentheses\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialUseConcurrentHashMap\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ControversialUseObjectForClearerAPI\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CouplingCouplingBetweenObjects\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CouplingExcessiveImports\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CouplingLawOfDemeter\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CouplingLooseCoupling\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"CouplingLoosePackageCoupling\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAbstractClassWithoutAbstractMethod\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAbstractClassWithoutAnyMethod\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAccessorClassGeneration\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAssignmentToNonFinalStatic\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAvoidConstantsInterface\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAvoidDeeplyNestedIfStmts\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAvoidInstanceofChecksInCatchClause\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAvoidProtectedFieldInFinalClass\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAvoidReassigningParameters\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignAvoidSynchronizedAtMethodLevel\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignBadComparison\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignClassWithOnlyPrivateConstructorsShouldBeFinal\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignCloseResource\" level=\"MAJOR\" enabled=\"true\">\n          <param name=\"types\" value=\"CMDBWrapper\" />\n          <param name=\"closeTargets\" value=\"closeQuietly, closeConnection, close\" />\n        </coding_rule>\n        <coding_rule class=\"DesignCompareObjectsWithEquals\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignConfusingTernary\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignConstructorCallsOverridableMethod\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignDefaultLabelNotLastInSwitchStmt\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignEmptyMethodInAbstractClassShouldBeAbstract\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignEqualsNull\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"DesignFieldDeclarationsShouldBeAtStartOfClass\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignFinalFieldCouldBeStatic\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignGodClass\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignIdempotentOperations\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignImmutableField\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignInstantiationToGetClass\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignLogicInversion\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignMissingBreakInSwitch\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"DesignMissingStaticMethodInNonInstantiatableClass\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignNonCaseLabelInSwitchStatement\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignNonStaticInitializer\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignNonThreadSafeSingleton\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignOptimizableToArrayCall\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignPositionLiteralsFirstInComparisons\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignPreserveStackTrace\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignReturnEmptyArrayRatherThanNull\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignSimpleDateFormatNeedsLocale\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignSimplifyBooleanExpressions\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignSimplifyBooleanReturns\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignSimplifyConditional\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignSingularField\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignSwitchDensity\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignSwitchStmtsShouldHaveDefault\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignTooFewBranchesForASwitchStatement\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUncommentedEmptyConstructor\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUncommentedEmptyMethod\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUnnecessaryLocalBeforeReturn\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUnsynchronizedStaticDateFormatter\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUseCollectionIsEmpty\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUseLocaleWithCaseConversions\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUseNotifyAllInsteadOfNotify\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUseSingleton\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"DesignUseVarargs\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyCatchBlock\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyFinallyBlock\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyIfStmt\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyInitializer\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyStatementBlock\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyStatementNotInLoop\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyStaticInitializer\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptySwitchStatements\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptySynchronizedBlock\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyTryBlock\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"EmptyCodeEmptyWhileStmt\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"FinalizerAvoidCallingFinalize\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"FinalizerEmptyFinalizer\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"FinalizerFinalizeDoesNotCallSuperFinalize\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"FinalizerFinalizeOnlyCallsSuperFinalize\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"FinalizerFinalizeOverloaded\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"FinalizerFinalizeShouldBeProtected\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ImportStatementsDontImportJavaLang\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ImportStatementsDuplicateImports\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ImportStatementsImportFromSamePackage\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"ImportStatementsTooManyStaticImports\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"ImportStatementsUnusedImports\" level=\"INFO\" enabled=\"false\" />\n        <coding_rule class=\"J2EEDoNotCallSystemExit\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EEDoNotUseThreads\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EELocalHomeNamingConvention\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EELocalInterfaceSessionNamingConvention\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EEMDBAndSessionBeanNamingConvention\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EERemoteInterfaceNamingConvention\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EERemoteSessionInterfaceNamingConvention\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EEStaticEJBFieldShouldBeFinal\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"J2EEUseProperClassLoader\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"JUnitJUnitAssertionsShouldIncludeMessage\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitJUnitSpelling\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitJUnitStaticSuite\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitJUnitTestContainsTooManyAsserts\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitJUnitTestsShouldIncludeAssert\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitSimplifyBooleanAssertion\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitTestClassWithoutTestCases\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitUnnecessaryBooleanAssertion\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitUseAssertEqualsInsteadOfAssertTrue\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitUseAssertNullInsteadOfAssertTrue\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitUseAssertSameInsteadOfAssertTrue\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JUnitUseAssertTrueInsteadOfAssertEquals\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JakartaCommonsLoggingGuardDebugLogging\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JakartaCommonsLoggingProperLogger\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JakartaCommonsLoggingUseCorrectExceptionLogging\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JavaBeansBeanMembersShouldSerialize\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JavaBeansMissingSerialVersionUID\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JavaLoggingAvoidPrintStackTrace\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JavaLoggingLoggerIsNotStaticFinal\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JavaLoggingMoreThanOneLogger\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"JavaLoggingSystemPrintln\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationAvoidAssertAsIdentifier\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationAvoidEnumAsIdentifier\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationByteInstantiation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationIntegerInstantiation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationJUnit4SuitesShouldUseSuiteAnnotation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationJUnit4TestShouldUseAfterAnnotation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationJUnit4TestShouldUseBeforeAnnotation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationJUnit4TestShouldUseTestAnnotation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationJUnitUseExpected\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationLongInstantiation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationReplaceEnumerationWithIterator\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationReplaceHashtableWithMap\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationReplaceVectorWithList\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"MigrationShortInstantiation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingAbstractNaming\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingAvoidDollarSigns\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingAvoidFieldNameMatchingMethodName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingAvoidFieldNameMatchingTypeName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingBooleanGetMethodName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingClassNamingConventions\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingGenericsNaming\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingLongVariable\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingMethodNamingConventions\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingMethodWithSameNameAsEnclosingClass\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingMisleadingVariableName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingNoPackage\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingPackageCase\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingShortClassName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingShortMethodName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingShortVariable\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingSuspiciousConstantFieldName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingSuspiciousEqualsMethodName\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"NamingSuspiciousHashcodeMethodName\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"NamingVariableNamingConventions\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationAddEmptyString\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationAvoidArrayLoops\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationAvoidInstantiatingObjectsInLoops\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationLocalVariableCouldBeFinal\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationMethodArgumentCouldBeFinal\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationPrematureDeclaration\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationRedundantFieldInitializer\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationSimplifyStartsWith\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationUnnecessaryWrapperObjectCreation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationUseArrayListInsteadOfVector\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationUseArraysAsList\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"OptimizationUseStringBufferForStringAppends\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"SecurityCodeGuidelinesArrayIsStoredDirectly\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"SecurityCodeGuidelinesMethodReturnsInternalArray\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidCatchingGenericException\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidCatchingNPE\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidCatchingThrowable\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidLosingExceptionInformation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidRethrowingException\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidThrowingNewInstanceOfSameException\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidThrowingNullPointerException\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsAvoidThrowingRawExceptionTypes\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsDoNotExtendJavaLangError\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsDoNotThrowExceptionInFinally\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsExceptionAsFlowControl\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StrictExceptionsSignatureDeclareThrowsException\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferAppendCharacterWithChar\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferAvoidDuplicateLiterals\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferAvoidStringBufferField\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferConsecutiveLiteralAppends\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferInefficientEmptyStringCheck\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferInefficientStringBuffering\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferInsufficientStringBufferDeclaration\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferStringBufferInstantiationWithChar\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferStringInstantiation\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferStringToString\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferUnnecessaryCaseChange\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferUseEqualsToCompareStrings\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferUseIndexOfChar\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferUseStringBufferLength\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"StringandStringBufferUselessStringValueOf\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"TypeResolutionCloneMethodMustImplementCloneable\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"TypeResolutionLooseCoupling\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"TypeResolutionSignatureDeclareThrowsException\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"TypeResolutionUnusedImports\" level=\"INFO\" enabled=\"false\" />\n        <coding_rule class=\"UnnecessaryUnnecessaryConversionTemporary\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnnecessaryUnnecessaryFinalModifier\" level=\"INFO\" enabled=\"false\" />\n        <coding_rule class=\"UnnecessaryUnnecessaryReturn\" level=\"MINOR\" enabled=\"false\" />\n        <coding_rule class=\"UnnecessaryUnusedNullCheckInEquals\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnnecessaryUselessOperationOnImmutable\" level=\"CRITICAL\" enabled=\"false\" />\n        <coding_rule class=\"UnnecessaryUselessOverridingMethod\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnnecessaryUselessParentheses\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnusedCodeUnusedFormalParameter\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnusedCodeUnusedLocalVariable\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnusedCodeUnusedModifier\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnusedCodeUnusedPrivateField\" level=\"MAJOR\" enabled=\"false\" />\n        <coding_rule class=\"UnusedCodeUnusedPrivateMethod\" level=\"MAJOR\" enabled=\"false\" />\n      </profile>\n    </profiles>\n    <list size=\"0\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/runConfigurations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <option name=\"ignoredProducers\">\n      <set>\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer\" />\n      </set>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2016 Pratyush Verma\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# DateTimeSeer\n### A painless way to pick future time\n\nDateTimeSeer is an android seer who gets visions of the date and time you are thinking. \n\nIt tells you what you might be thinking and helps in what modern people call as autocompletion. Unfortunately, he currently knows only english.\n\n![Demo](demo/demo.gif)\n\n**Gradle**\n\nAdd the seer to `build.gradle` and you are good to go,\n\n```groovy\ndependencies {\n    compile 'com.pv:datetimeseer:1.0.0'\n}\n```\n\nThe library exposes `SeerFilter` which extends android's `Filter` class and so can be hooked to anything which implements `Filterable`. \n\nUse the `ConfigBuilder` to provide Date/Time formats.\n\nThe sample app here demonstrate the usage of the `Filter` with the `AutoCompleteTextView`. \n\n\n### Contributing\n\nFor other languages support, \n\n- Checkout the `dev` branch \n- Implement the changes for the language in [this package](https://github.com/p-v/DateTimeSeer/tree/dev/library/src/main/java/com/pv/datetimeseer/parser/handler). Check the [english language implementation](https://github.com/p-v/DateTimeSeer/tree/dev/library/src/main/java/com/pv/datetimeseer/parser/handler/english) for reference.  \n- Add the `strings.xml`  file for the language\n- Add the language to `Config.java`\n- Update `getLocaleFromLanguage` in `DateTimeUtils.java`\n- Initialize the handlers created in `SeerParserInitializer.java` for the language\n\nFeel free to create an issue in case of any implementation issues. Or email me at the address present on my profile. \n\n### TODOS\n\n- Add more documentation\n- Some dirty code clean up\n\n\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"24.0.1\"\n    defaultConfig {\n        applicationId \"com.pv.sample\"\n        minSdkVersion 15\n        targetSdkVersion 24\n        versionCode 1\n        versionName \"1.0\"\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile project(':library')\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n    compile 'com.android.support:appcompat-v7:24.2.0'\n    testCompile 'junit:junit:4.12'\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/p-v/developer_tools/android-sdk-macosx/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "app/src/androidTest/java/com/pv/sample/ExampleInstrumentedTest.java",
    "content": "package com.pv.sample;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.pv.sample\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.pv.sample\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/com/pv/sample/AwesomeAdapter.java",
    "content": "package com.pv.sample;\n\nimport android.content.Context;\nimport android.support.annotation.NonNull;\nimport android.support.annotation.Nullable;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ArrayAdapter;\nimport android.widget.Filter;\nimport android.widget.Filterable;\nimport android.widget.TextView;\n\nimport com.pv.datetimeseer.Config;\nimport com.pv.datetimeseer.SeerFilter;\nimport com.pv.datetimeseer.SuggestionRow;\n\nimport java.util.List;\n\n/**\n * @author p-v\n */\n\npublic class AwesomeAdapter extends ArrayAdapter<SuggestionRow> implements Filterable {\n\n    private SeerFilter suggestionFilter;\n    private List<SuggestionRow> suggestionRowList;\n\n    public AwesomeAdapter(Context context, int resource) {\n        super(context, resource);\n    }\n\n    @Override\n    public int getCount() {\n        return suggestionRowList == null ? 0 : suggestionRowList.size();\n    }\n\n    @Nullable\n    @Override\n    public SuggestionRow getItem(int position) {\n        return suggestionRowList.get(position);\n    }\n\n    @NonNull\n    @Override\n    public Filter getFilter() {\n        if (suggestionFilter == null) {\n            Config config = new Config.ConfigBuilder()\n                    .setTimeFormat12HoursWithMins(\"h:mm a\")\n                    .setTimeFormat12HoursWithoutMins(\"h a\")\n                    .build();\n\n            suggestionFilter =  new SeerFilter(getContext(), config);\n            suggestionFilter.setOnSuggestionPublishListener(new SeerFilter.OnSuggestionPublishListener() {\n                @Override\n                public void onSuggestionPublish(List<SuggestionRow> suggestionList) {\n                    AwesomeAdapter.this.suggestionRowList = suggestionList;\n                    if (suggestionList != null) {\n                        AwesomeAdapter.this.notifyDataSetChanged();\n                    } else {\n                        AwesomeAdapter.this.notifyDataSetInvalidated();\n                    }\n                }\n            });\n        }\n        return suggestionFilter;\n    }\n\n    @NonNull\n    @Override\n    public View getView(int position, View convertView, @NonNull  ViewGroup parent) {\n        if (convertView == null) {\n            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.suggestion_row, parent, false);\n        }\n        TextView textView = (TextView) convertView\n                .findViewById(R.id.suggestion_textView);\n        SuggestionRow suggestion = getItem(position);\n        if (suggestion != null) {\n            textView.setText(suggestion.getDisplayValue());\n        }\n        return convertView;\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/pv/sample/MainActivity.java",
    "content": "package com.pv.sample;\n\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\nimport android.view.View;\nimport android.widget.AdapterView;\nimport android.widget.AutoCompleteTextView;\nimport android.widget.Toast;\n\nimport com.pv.datetimeseer.SuggestionRow;\n\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Locale;\n\npublic class MainActivity extends AppCompatActivity {\n\n    private AwesomeAdapter awesomeAdapter;\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n\n        final AutoCompleteTextView autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.awesome_view);\n        autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {\n            @Override\n            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\n                if (awesomeAdapter != null) {\n                    SuggestionRow suggestionRow = awesomeAdapter.getItem(position);\n                    if (suggestionRow != null) {\n                        String displayText;\n                        if (suggestionRow.getValue() == SuggestionRow.PARTIAL_VALUE) {\n                            displayText = suggestionRow.getDisplayValue() + \" \";\n                            // show dropdown for partial values\n                            autoCompleteTextView.post(new Runnable() {\n                                @Override\n                                public void run() {\n                                    autoCompleteTextView.showDropDown();\n                                }\n                            });\n                        } else {\n                            displayText = suggestionRow.getDisplayValue();\n                            long selectedTime = suggestionRow.getValue() * 1000L;\n                            DateFormat df = new SimpleDateFormat(\"EEEE, d MMMM yyyy h:mma\", Locale.ENGLISH);\n                            String timeOnScreen = df.format(new Date(selectedTime));\n                            Toast.makeText(MainActivity.this, String.format(getString(R.string.awesome_time),\n                                    timeOnScreen), Toast.LENGTH_SHORT).show();\n                        }\n                        autoCompleteTextView.setText(displayText);\n                        autoCompleteTextView.setSelection(displayText.length());\n                    }\n                }\n            }\n        });\n        awesomeAdapter = new AwesomeAdapter(this, android.R.layout.simple_dropdown_item_1line);\n        autoCompleteTextView.setAdapter(awesomeAdapter);\n    }\n}\n"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/activity_main\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    tools:context=\"com.pv.sample.MainActivity\">\n\n    <AutoCompleteTextView\n        android:id=\"@+id/awesome_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:hint=\"@string/auto_complete_hint\"\n        />\n\n    <TextView\n        android:id=\"@+id/examples_title\"\n        android:textSize=\"16sp\"\n        android:textStyle=\"bold\"\n        android:text=\"@string/examples_title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"16sp\"\n        android:text=\"@string/examples\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/suggestion_row.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\nandroid:layout_width=\"match_parent\"\nandroid:layout_height=\"wrap_content\"\nandroid:layout_gravity=\"center_vertical\"\nandroid:descendantFocusability=\"blocksDescendants\"\nandroid:gravity=\"center_vertical\"\nandroid:orientation=\"horizontal\" >\n\n<TextView\n    android:id=\"@+id/suggestion_textView\"\n    android:background=\"@android:color/white\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_vertical\"\n    android:ellipsize=\"end\"\n    android:lines=\"1\"\n    android:paddingTop=\"15dp\"\n    android:paddingBottom=\"15dp\"\n    android:paddingLeft=\"5dp\"\n    android:paddingRight=\"5dp\"\n    android:singleLine=\"true\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">DateTimeSeerSample</string>\n    <string name=\"auto_complete_hint\">Awesomeness waiting for you…</string>\n    <string name=\"examples_title\">Try some of these:</string>\n    <string name=\"examples\">Tom\\nTomorrow\\nTomorrow morning\\ntomorrow evening\\n3 days\\n50m\\n10mins\\n3 months</string>\n    <string name=\"awesome_time\">%s sounds amazing</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "content": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as screen margins) for screens with more than 820dp of available width. This\n         would include 7\" and 10\" devices in landscape (~960dp and ~1280dp respectively). -->\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/test/java/com/pv/sample/ExampleUnitTest.java",
    "content": "package com.pv.sample;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:2.2.0'\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.3'\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.14.1-all.zip\n"
  },
  {
    "path": "gradle-mvn-push.gradle",
    "content": "group = PROJ_GROUP\nversion = PROJ_VERSION\nproject.archivesBaseName = PROJ_ARTIFACTID\n\napply plugin: 'com.jfrog.bintray'\napply plugin: 'maven-publish'\n\ntask sourcesJar(type: Jar) {\n    from android.sourceSets.main.java.srcDirs\n    classifier = 'sources'\n}\n\ntask javadoc(type: Javadoc) {\n    source = android.sourceSets.main.java.srcDirs\n    classpath += configurations.compile\n    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))\n    failOnError false\n}\n\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n    classifier = 'javadoc'\n    from javadoc.destinationDir\n}\n\njavadoc {\n    options{\n        encoding \"UTF-8\"\n        charSet 'UTF-8'\n        author true\n        version true\n        links \"http://docs.oracle.com/javase/7/docs/api\"\n        title PROJ_ARTIFACTID\n    }\n}\n\nartifacts {\n    archives javadocJar\n    archives sourcesJar\n}\n\ndef pomConfig = {\n    licenses {\n        license {\n            name \"MIT\"\n            url \"https://raw.githubusercontent.com/p-v/DateTimeSeer/master/LICENSE\"\n            distribution \"repo\"\n        }\n    }\n    developers {\n        developer {\n            id DEVELOPER_ID\n            name DEVELOPER_NAME\n            email DEVELOPER_EMAIL\n        }\n    }\n}\n\npublishing {\n    publications {\n        mavenJava(MavenPublication) {\n            artifactId PROJ_ARTIFACTID\n\n            pom{\n                packaging 'aar'\n            }\n            pom.withXml {\n                def root = asNode()\n                root.appendNode('description', PROJ_DESCRIPTION)\n                root.children().last() + pomConfig\n            }\n        }\n    }\n}\n\nbintray {\n    Properties properties = new Properties()\n    properties.load(project.rootProject.file('local.properties').newDataInputStream())\n    user = properties.getProperty('BINTRAY_USER')\n    key = properties.getProperty('BINTRAY_KEY')\n\n    configurations = ['archives']\n    publications = ['mavenJava']\n    publish = true\n\n    pkg {\n        repo = 'maven'\n        name = PROJ_NAME\n        desc = PROJ_DESCRIPTION\n        websiteUrl = PROJ_WEBSITEURL\n        issueTrackerUrl = PROJ_ISSUETRACKERURL\n        vcsUrl = PROJ_VCSURL\n        licenses = ['MIT']\n        publicDownloadNumbers = true\n    }\n}\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\nPROJ_GROUP=com.pv\nPROJ_VERSION=1.0.0\nPROJ_NAME=DateTimeSeer\nPROJ_WEBSITEURL=https://github.com/p-v/DateTimeSeer\nPROJ_ISSUETRACKERURL=https://github.com/p-v/DateTimeSeer/issues\nPROJ_VCSURL=https://github.com/p-v/DateTimeSeer.git\nPROJ_DESCRIPTION=A seer who gets visions of the date and time you are thinking while typing. \nPROJ_ARTIFACTID=datetimeseer\n\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "library/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "library/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 24\n    buildToolsVersion \"24.0.1\"\n\n    defaultConfig {\n        minSdkVersion 14\n        targetSdkVersion 24\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {\n        exclude group: 'com.android.support', module: 'support-annotations'\n    })\n    compile 'com.android.support:appcompat-v7:24.2.0'\n    testCompile 'junit:junit:4.12'\n}\n\n//apply from: '../gradle-mvn-push.gradle'\n"
  },
  {
    "path": "library/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/p-v/developer_tools/android-sdk-macosx/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "library/src/androidTest/java/com/pv/datetimeseer/ExampleInstrumentedTest.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport android.support.test.runner.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumentation test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() throws Exception {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getTargetContext();\n\n        assertEquals(\"com.pv.datetimeseer.test\", appContext.getPackageName());\n    }\n}\n"
  },
  {
    "path": "library/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.pv.datetimeseer\">\n\n    <application android:allowBackup=\"true\" android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/Config.java",
    "content": "package com.pv.datetimeseer;\n\n/**\n * @author p-v\n */\n\npublic class Config {\n\n    private final String dateFormatWithYear;\n    private final String dateFormatWithoutYear;\n    private final String timeFormat24Hours;\n    private final String timeFormat12HoursWithMins;\n    private final String timeFormat12HoursWithoutMins;\n\n    private Config(ConfigBuilder builder) {\n        this.dateFormatWithYear = builder.dateFormatWithYear;\n        this.dateFormatWithoutYear = builder.dateFormatWithoutYear;\n        this.timeFormat24Hours = builder.timeFormat24Hours;\n        this.timeFormat12HoursWithMins = builder.timeFormat12HoursWithMins;\n        this.timeFormat12HoursWithoutMins = builder.timeFormat12HoursWithoutMins;\n    }\n\n    public String getDateFormatWithYear() {\n        return dateFormatWithYear == null ? Constants.DATE_FORMAT_WITH_YEAR : dateFormatWithYear;\n    }\n\n    public String getDateFormatWithoutYear() {\n        return dateFormatWithoutYear == null ? Constants.DATE_FORMAT : dateFormatWithoutYear;\n    }\n\n    public String getTimeFormat24Hours() {\n        return timeFormat24Hours == null ? Constants.TIME_FORMAT_24HOUR : timeFormat24Hours;\n    }\n\n    public String getTimeFormat12HoursWithMins() {\n        return timeFormat12HoursWithMins == null ?\n                Constants.TIME_FORMAT_12HOUR_WITH_MINS : timeFormat12HoursWithMins;\n    }\n\n    public String getTimeFormat12HoursWithoutMins() {\n        return timeFormat12HoursWithoutMins == null ?\n                Constants.TIME_FORMAT_12HOUR_WITHOUT_MINS : timeFormat12HoursWithoutMins;\n    }\n\n\n    public static class ConfigBuilder {\n\n        private String dateFormatWithYear;\n        private String dateFormatWithoutYear;\n        private String timeFormat24Hours;\n        private String timeFormat12HoursWithMins;\n        private String timeFormat12HoursWithoutMins;\n\n        public ConfigBuilder setDateFormatWithYear(String dateFormatWithYear) {\n            this.dateFormatWithYear = dateFormatWithYear;\n            return this;\n        }\n\n        public ConfigBuilder setDateFormatWithoutYear(String dateFormatWithoutYear) {\n            this.dateFormatWithoutYear = dateFormatWithoutYear;\n            return this;\n        }\n\n        public ConfigBuilder setTimeFormat24Hours(String timeFormat24Hours) {\n            this.timeFormat24Hours = timeFormat24Hours;\n            return this;\n        }\n\n        public ConfigBuilder setTimeFormat12HoursWithMins(String timeFormat12HoursWithMins) {\n            this.timeFormat12HoursWithMins = timeFormat12HoursWithMins;\n            return this;\n        }\n\n        public ConfigBuilder setTimeFormat12HoursWithoutMins(String timeFormat12HoursWithoutMins) {\n            this.timeFormat12HoursWithoutMins = timeFormat12HoursWithoutMins;\n            return this;\n        }\n\n        public Config build() {\n            return new Config(this);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/Constants.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.support.annotation.IntDef;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\n/**\n * @author p-v\n */\n\nclass Constants {\n\n    @IntDef({Weekend.SATURDAY_SUNDAY, Weekend.FRIDAY_SATURDAY,\n            Weekend.THURSDAY_FRIDAY, Weekend.FRIDAY_ONLY,\n            Weekend.SATURDAY_ONLY, Weekend.SUNDAY_ONLY})\n\n    @Retention(RetentionPolicy.SOURCE)\n    @interface Weekend {\n        int SATURDAY_SUNDAY = 0;\n        int FRIDAY_SATURDAY = 1;\n        int THURSDAY_FRIDAY = 2;\n        int FRIDAY_ONLY = 3;\n        int SATURDAY_ONLY = 4;\n        int SUNDAY_ONLY = 5;\n    }\n\n    static final int NEXT_WEEK_THRESHOLD = 4;\n\n    static final String DATE_FORMAT = \"EEEE, d MMMM\";\n    static final String DATE_FORMAT_WITH_YEAR = \"EEEE, d MMMM yyyy\";\n    static final String TIME_FORMAT_24HOUR = \"H:mm\";\n    static final String TIME_FORMAT_12HOUR_WITH_MINS = \"h:mma\";\n    static final String TIME_FORMAT_12HOUR_WITHOUT_MINS = \"ha\";\n\n    static final String MONTH_FORMAT_SHORT = \"MMM\";\n    static final String MONTH_FORMAT_LONG = \"MMMM\";\n\n\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/DOWSuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Suggestion handler for Day of Week.<br/>\n * Handles strings such as, next friday, fri, tuesday<br/>\n * Also handles partial strings such as tues, thus\n *\n * @author p-v\n */\nclass DOWSuggestionHandler extends SuggestionHandler {\n\n    private static final String DAY_OF_WEEK = \"(next\\\\s{0,2})?(?:\\\\b(?:(?:(mon)|(fri)|(sun))(?:d(?:ay?)?)?)|\\\\b(tue(?:s(?:d(?:ay?)?)?)?)|\\\\b(wed(?:n(?:e(?:s(?:d(?:ay?)?)?)?)?)?)|\\\\b(thu(?:r(?:s(?:d(?:ay?)?)?)?)?)|\\\\b(sat(?:u(?:r(?:d(?:ay?)?)?)?)?))\\\\b\";\n    private Pattern pDow;\n\n    DOWSuggestionHandler(Config config) {\n        super(config);\n        pDow = Pattern.compile(DAY_OF_WEEK, Pattern.CASE_INSENSITIVE);\n    }\n\n    @Override\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n        Matcher matcher = pDow.matcher(input);\n        if (matcher.find()) {\n            int value = -1;\n            if (matcher.group(2) != null) {\n                // Monday\n                value = Calendar.MONDAY;\n            } else if (matcher.group(3) != null) {\n                // Friday\n                value = Calendar.FRIDAY;\n            } else if (matcher.group(4) != null) {\n                // Sunday\n                value = Calendar.SUNDAY;\n            } else if (matcher.group(5) != null) {\n                // Tuesday\n                value = Calendar.TUESDAY;\n            } else if (matcher.group(6) != null) {\n                // Wednesday\n                value = Calendar.WEDNESDAY;\n            } else if (matcher.group(7) != null) {\n                // Thursday\n                value = Calendar.THURSDAY;\n            } else if (matcher.group(8) != null) {\n                // Saturday\n                value = Calendar.SATURDAY;\n            }\n            if (value != -1) {\n                if (matcher.group(1) != null) {\n                    suggestionValue.appendSuggestion(SuggestionValue.DAY_OF_WEEK_NEXT, value);\n                } else {\n                    suggestionValue.appendSuggestion(SuggestionValue.DAY_OF_WEEK, value);\n                }\n            }\n        }\n\n        super.handle(context, input, lastToken, suggestionValue);\n    }\n\n    @Override\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        SuggestionValue.LocalItemItem dowItem = suggestionValue.getDowItem();\n        SuggestionValue.LocalItemItem nextDowItem = suggestionValue.getNextDowItem();\n\n        // Check whether to handle or not\n        if (dowItem != null || nextDowItem != null) {\n\n            // Time related items\n            SuggestionValue.LocalItemItem todItem = suggestionValue.getTodItem();\n            TimeSuggestionHandler.TimeItem timeItem = suggestionValue.getTimeItem();\n\n            // Initialize user value and current day value\n            Calendar cal = Calendar.getInstance();\n            final int currentDayOfWeek = cal.get(Calendar.DAY_OF_WEEK);\n            final int actualUserValue = dowItem != null ? dowItem.value : nextDowItem.value;\n\n            int daysToAdd;\n            if (currentDayOfWeek < actualUserValue) {\n                // day of week user value is less than the current day value\n                // example user value Saturday = 7 and current day is Friday 6\n                daysToAdd = actualUserValue - currentDayOfWeek;\n            } else {\n                // day of week user value is more than the current day value\n                // example user value Monday = 1 and current day is Saturday 7\n                daysToAdd = 7 - (currentDayOfWeek - actualUserValue);\n            }\n\n            // User inputs the day same as today, then consider the next day of week\n            if (dowItem != null && daysToAdd == 0) {\n                daysToAdd += 7;\n            }\n\n            // For next day of the week item add 7 days if the day is within the threshold value\n            if (nextDowItem != null && daysToAdd < Constants.NEXT_WEEK_THRESHOLD) {\n                daysToAdd += 7;\n            }\n\n            // Compute display and real value if time items are  not null\n            Value timeValue;\n            if (todItem != null || timeItem != null) {\n                if (todItem == null) {\n                    // timeItem is not null here\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n                } else {\n                    timeValue = getTimeValue(context, todItem, timeItem);\n                }\n\n                timeValue.value.add(Calendar.DAY_OF_WEEK, daysToAdd);\n\n                // add to suggestion list\n                suggestionList.add(new SuggestionRow(getDisplayDate(context,\n                        timeValue.value, timeValue.displayString),\n                        (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                timeValue.value.add(Calendar.DAY_OF_WEEK, 7);\n                suggestionList.add(new SuggestionRow(getDisplayDate(context,\n                        timeValue.value, timeValue.displayString),\n                        (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                timeValue.value.add(Calendar.DAY_OF_WEEK, 7);\n                suggestionList.add(new SuggestionRow(getDisplayDate(context,\n                        timeValue.value, timeValue.displayString),\n                        (int)(timeValue.value.getTimeInMillis()/1000)));\n            } else {\n                // Create 3 partial date suggestions\n                cal = Calendar.getInstance();\n                cal.add(Calendar.DAY_OF_WEEK , daysToAdd);\n                // first suggestion\n                suggestionList.add(new SuggestionRow(DateTimeUtils.getDisplayDate(cal, config),\n                        SuggestionRow.PARTIAL_VALUE));\n\n                // second suggestion\n                cal.add(Calendar.DAY_OF_WEEK , 7);\n                suggestionList.add(new SuggestionRow(DateTimeUtils.getDisplayDate(cal, config),\n                        SuggestionRow.PARTIAL_VALUE));\n\n                // third suggestion\n                cal.add(Calendar.DAY_OF_WEEK , 7);\n                suggestionList.add(new SuggestionRow(DateTimeUtils.getDisplayDate(cal, config),\n                        SuggestionRow.PARTIAL_VALUE));\n            }\n\n\n        } else {\n            super.build(context, suggestionValue, suggestionList);\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/DateSuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * @author p-v\n */\nclass DateSuggestionHandler extends SuggestionHandler {\n\n    private static final String DATE_RGX = \"\\\\b(?:(0?[1-9]|[12][0-9]|3[01])(?:st|nd|rd|th)?\\\\s+\\\\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec|january|february|march|april|may|june|july|august|september|october|november|december)\\\\b(?:(?:,?\\\\s*)(?:(?:20)?(\\\\d\\\\d)(?!:)))?|(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec|january|february|march|april|may|june|july|august|september|october|november|december)\\\\s+(0?[1-9]|[12][0-9]|3[01])(?:st|nd|rd|th)?\\\\b(?:(?:,?\\\\s*)(?:\\\\b(?:20)?(\\\\d\\\\d)(?!:))\\\\b)?)\\\\b\";\n    private Pattern pDate;\n\n    static class DateItem extends SuggestionValue.LocalItemItem {\n\n        int startIdx;\n        int endIdx;\n\n        DateItem(int value, int startIdx, int endIdx) {\n            super(value);\n            this.startIdx = startIdx;\n            this.endIdx = endIdx;\n        }\n    }\n\n    DateSuggestionHandler(Config config) {\n        super(config);\n        pDate = Pattern.compile(DATE_RGX, Pattern.CASE_INSENSITIVE);\n    }\n\n    @Override\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n        Matcher m = pDate.matcher(input);\n\n        if (m.find()) {\n            int dayOfMonth;\n            int year = 0;\n            String month;\n            String yearStr;\n            if (m.group(1) != null) {\n                dayOfMonth = Integer.parseInt(m.group(1));\n                month = m.group(2);\n                yearStr = m.group(3);\n            } else {\n                dayOfMonth = Integer.parseInt(m.group(5));\n                month = m.group(4);\n                yearStr = m.group(6);\n            }\n            if (yearStr != null) {\n                year = 2000 + Integer.parseInt(yearStr);\n            }\n            DateFormat fmt;\n            if(month.length() == 3){\n                fmt = new SimpleDateFormat(Constants.MONTH_FORMAT_SHORT, Locale.ENGLISH);\n            }else{\n                fmt = new SimpleDateFormat(Constants.MONTH_FORMAT_LONG, Locale.ENGLISH);\n            }\n            Date date = null;\n            try {\n                date = fmt.parse(month);\n            } catch (ParseException e) {\n                e.printStackTrace();\n            }\n            Calendar cal = Calendar.getInstance();\n\n            int currentYear = cal.get(Calendar.YEAR);\n            if (year > 0 && year >= currentYear) {\n                cal.set(Calendar.YEAR, year);\n            }\n            cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);\n            cal.set(Calendar.HOUR_OF_DAY, 0);\n            cal.set(Calendar.MINUTE, 0);\n            cal.set(Calendar.SECOND, 0);\n            cal.set(Calendar.MILLISECOND, 0);\n            if (date != null) {\n                Calendar ctemp = Calendar.getInstance();\n                ctemp.setTime(date);\n                cal.set(Calendar.MONTH, ctemp.get(Calendar.MONTH));\n            }\n            suggestionValue.appendSuggestion(SuggestionValue.DATE,\n                    new DateItem((int)(cal.getTimeInMillis()/1000), m.start(), m.end()));\n        }\n\n        super.handle(context, input, lastToken, suggestionValue);\n    }\n\n    @Override\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        DateItem dateItem = suggestionValue.getDateItem();\n        if (dateItem != null) {\n            SuggestionValue.LocalItemItem todItem = suggestionValue.getTodItem();\n            TimeSuggestionHandler.TimeItem timeItem = suggestionValue.getTimeItem();\n\n            Value timeValue = null;\n            int secondsOfDay = 0;\n            if (todItem != null || timeItem != null) {\n                if (todItem == null) {\n                    // timeItem is not null here\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n                    secondsOfDay = timeItem.value * 60;\n                } else {\n                    timeValue = getTimeValue(context, todItem, timeItem);\n                    secondsOfDay = 60 * (timeValue.value.get(Calendar.MINUTE)\n                            + timeValue.value.get(Calendar.HOUR_OF_DAY) * 60);\n                }\n\n            }\n\n            Calendar cal = Calendar.getInstance();\n            boolean incrementYear = false;\n            if (cal.getTimeInMillis() / 1000 > (dateItem.value + secondsOfDay)) {\n                // current time is more than the specified date\n                incrementYear = true;\n            }\n            cal.setTimeInMillis(dateItem.value * 1000L);\n            if (incrementYear) {\n                cal.add(Calendar.YEAR, 1);\n            }\n\n            if (timeValue == null) {\n                if (DateTimeUtils.isWeekend(cal.get(Calendar.DAY_OF_WEEK), WEEKEND)) {\n                    int morningTime = MORNING_TIME_WEEKEND;\n                    int hour = morningTime / 60;\n                    int mins = morningTime % 60;\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n                } else {\n                    int morningTime = MORNING_TIME_WEEKDAY;\n                    int hour = morningTime / 60;\n                    int mins = morningTime % 60;\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n                }\n\n                // show multiple suggestions\n                // update time value\n                timeValue.value.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR));\n                timeValue.value.set(Calendar.YEAR, cal.get(Calendar.YEAR));\n\n                String displayDate = getDisplayDate(timeValue.value);\n\n                // first item\n                suggestionList.add(new SuggestionRow(displayDate + \", \"\n                        + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                //second item\n                int afternoonTime = AFTERNOON_TIME;\n                int hour = afternoonTime / 60;\n                int mins = afternoonTime % 60;\n                timeValue.value.set(Calendar.HOUR_OF_DAY, hour);\n                timeValue.value.set(Calendar.MINUTE, mins);\n                suggestionList.add(new SuggestionRow(displayDate + \", \"\n                        + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                //third item\n                timeValue.value.set(Calendar.HOUR_OF_DAY, 12 + EVENING_TIME);\n                timeValue.value.set(Calendar.MINUTE, 0);\n                suggestionList.add(new SuggestionRow(displayDate + \", \"\n                        + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n            } else {\n                // just show one suggestion as the time is specified with date\n                // update time value\n                timeValue.value.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR));\n                timeValue.value.set(Calendar.YEAR, cal.get(Calendar.YEAR));\n\n                suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value) + \", \"\n                        + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n            }\n\n\n        } else {\n            super.build(context, suggestionValue, suggestionList);\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/DateTimeUtils.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.Locale;\n\n/**\n * @author p-v\n */\n@SuppressWarnings(\"WrongConstant\")\nclass DateTimeUtils {\n\n    static String getDisplayDate(Calendar cal, Config config) {\n        DateFormat df = new SimpleDateFormat(config.getDateFormatWithoutYear(), Locale.ENGLISH);\n        return df.format(cal.getTime());\n    }\n\n    static String getDisplayTime(Context context, Calendar cal, Config config) {\n\n        String format;\n        if (android.text.format.DateFormat.is24HourFormat(context)) {\n            format = config.getTimeFormat24Hours();\n        } else {\n            if (cal.get(Calendar.MINUTE) == 0) {\n                format = config.getTimeFormat12HoursWithoutMins();\n            } else {\n                format = config.getTimeFormat12HoursWithMins();\n            }\n        }\n        DateFormat df = new SimpleDateFormat(format, Locale.ENGLISH);\n        return df.format(cal.getTime());\n    }\n\n    static int daysBetween(Calendar day1, Calendar day2) {\n        /**\n         * Saved some effort using the solution described here,\n         * http://stackoverflow.com/a/28865648/1587370\n         */\n        Calendar dayOne = (Calendar) day1.clone(),\n                dayTwo = (Calendar) day2.clone();\n\n        if (dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR)) {\n            return Math.abs(dayOne.get(Calendar.DAY_OF_YEAR) - dayTwo.get(Calendar.DAY_OF_YEAR));\n        } else {\n            if (dayTwo.get(Calendar.YEAR) > dayOne.get(Calendar.YEAR)) {\n                //swap them\n                Calendar temp = dayOne;\n                dayOne = dayTwo;\n                dayTwo = temp;\n            }\n            int extraDays = 0;\n\n            int dayOneOriginalYearDays = dayOne.get(Calendar.DAY_OF_YEAR);\n\n            while (dayOne.get(Calendar.YEAR) > dayTwo.get(Calendar.YEAR)) {\n                dayOne.add(Calendar.YEAR, -1);\n                // getActualMaximum() important for leap years\n                extraDays += dayOne.getActualMaximum(Calendar.DAY_OF_YEAR);\n            }\n\n            return extraDays - dayTwo.get(Calendar.DAY_OF_YEAR) + dayOneOriginalYearDays;\n        }\n    }\n\n    /**\n     * Determines if the passed day of week is weekend\n     *\n     * @param dayOfWeek day to determine\n     * @param weekendValue user's weekend value\n     * @return true if weekend, false otherwise\n     */\n    static boolean isWeekend(int dayOfWeek,\n                                    @Constants.Weekend int weekendValue) {\n        switch (weekendValue) {\n            case Constants.Weekend.SATURDAY_SUNDAY:\n                return Calendar.SATURDAY == dayOfWeek || Calendar.SUNDAY == dayOfWeek;\n            case Constants.Weekend.FRIDAY_SATURDAY:\n                return Calendar.FRIDAY == dayOfWeek || Calendar.SATURDAY == dayOfWeek;\n            case Constants.Weekend.THURSDAY_FRIDAY:\n                return Calendar.THURSDAY == dayOfWeek || Calendar.FRIDAY == dayOfWeek;\n            case Constants.Weekend.FRIDAY_ONLY:\n                return Calendar.FRIDAY == dayOfWeek;\n            case Constants.Weekend.SATURDAY_ONLY:\n                return Calendar.SATURDAY == dayOfWeek;\n            case Constants.Weekend.SUNDAY_ONLY:\n                return Calendar.SUNDAY == dayOfWeek;\n            default:\n                return false;\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/InitialSuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Initial suggestion handler used for suggesting values and ignoring other handlers\n * if its able to handle the input\n *\n * @author p-v\n */\nclass InitialSuggestionHandler extends SuggestionHandler {\n\n    private static final String REGEX = \"^\\\\s*(\\\\d{1,2})\\\\s*$\";\n\n    private Pattern p;\n\n    InitialSuggestionHandler(Config config) {\n        super(config);\n        p = Pattern.compile(REGEX);\n    }\n\n    @Override\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n        if (input.trim().length() == 2 && input.trim().matches(\"(?i)^to\")) {\n            // if only 2 char input is there and that is 't0', do not go further,\n            // consider it as today and tomorrow, and show suggestions accordingly\n            suggestionValue.appendSuggestion(SuggestionValue.OTHER, 0);\n        } else {\n            // check if the input has only numbers\n            Matcher m = p.matcher(input);\n            if (m.find()) {\n                int number = Integer.parseInt(m.group(1));\n                if (number > 0) {\n                    suggestionValue.appendSuggestion(SuggestionValue.NUMBER, number);\n                } else {\n                    super.handle(context, input, lastToken, suggestionValue);\n                }\n            } else {\n                super.handle(context, input, lastToken, suggestionValue);\n            }\n        }\n    }\n\n    @Override\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        SuggestionValue.LocalItemItem numItem = suggestionValue.getNumberItem();\n        SuggestionValue.LocalItemItem otherItem = suggestionValue.getOtherItem();\n        if (numItem != null && numItem.value <= 31) {\n            int number = numItem.value;\n\n            Value timeValue;\n            if (number < 24) {\n                Calendar cal = Calendar.getInstance();\n                final int currentHourOfDay = cal.get(Calendar.HOUR_OF_DAY);\n\n                // consider it as time other wise date\n                // first time from now be it am or pm\n                timeValue = getTimeValue(context, number, 0, currentHourOfDay >= 12 ? \"pm\" : \"am\", null);\n\n\n                // first item\n                if (currentHourOfDay < timeValue.value.get(Calendar.HOUR_OF_DAY)) {\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                } else {\n                    // increment 12 hours\n                    timeValue.value.add(Calendar.HOUR_OF_DAY, 12);\n                    // if same day show today otherwise tomorrow\n                    if (cal.get(Calendar.DAY_OF_YEAR) == timeValue.value.get(Calendar.DAY_OF_YEAR)) {\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                                + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                    } else{\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                                + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                    }\n                }\n\n                // second item\n                // increment 12 hours\n                timeValue.value.add(Calendar.HOUR_OF_DAY, 12);\n                // if same day show today otherwise tomorrow\n                if (cal.get(Calendar.DAY_OF_YEAR) == timeValue.value.get(Calendar.DAY_OF_YEAR)) {\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                } else{\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                            + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                }\n            }\n\n            Calendar cal = Calendar.getInstance();\n            int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);\n\n            int currentDayOfMonth = cal.get(Calendar.DAY_OF_MONTH);\n\n            if (currentDayOfMonth < number && number <= maxDay) {\n                cal.set(Calendar.DAY_OF_MONTH, number);\n            } else {\n                cal.add(Calendar.MONTH, 1);\n                // TODO revisit someday\n                maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);\n                cal.set(Calendar.DAY_OF_MONTH, maxDay < number ? maxDay : number);\n            }\n            suggestionList.add(new SuggestionRow(DateTimeUtils.getDisplayDate(cal, config), SuggestionRow.PARTIAL_VALUE));\n\n        } else if (otherItem != null) {\n            suggestionList.add(new SuggestionRow(context.getString(R.string.today), SuggestionRow.PARTIAL_VALUE));\n            suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow), SuggestionRow.PARTIAL_VALUE));\n        } else {\n            super.build(context, suggestionValue, suggestionList);\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/NumberRelativeTimeSuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n *\n * Relative time suggestion handler<br/><br/>\n *\n * e.g. <br/>after 6 hours<br/>\n * 6mins<br/>\n * 10 days<br/>\n * after 2 months<br/>\n *\n * @author p-v\n */\nclass NumberRelativeTimeSuggestionHandler extends SuggestionHandler {\n\n    private static final String REGEX = \"\\\\b(?:(?:(?:(?:after\\\\s{1,2})?(\\\\d\\\\d?)\\\\s{0,2})|next\\\\s{1,2})(?:(month?)|(m(?:i(?:n(?:u(?:te?)?)?)?)?)|(we(?:ek?))|(d(?:ay?))|(hr|h(?:o(?:ur?)?)?))s?)\\\\b\";\n    private Pattern pRel;\n\n    class RelativeDayNumItem extends SuggestionValue.LocalItemItem {\n\n        static final int DAY = 1;\n        static final int HOUR = 2;\n        static final int MIN = 3;\n        static final int WEEK = 4;\n        static final int MONTH = 5;\n\n        int type;\n        int startIdx;\n        int endIdx;\n\n        RelativeDayNumItem(int value, int type, int startIdx, int endIdx) {\n            super(value);\n            this.type = type;\n            this.startIdx = startIdx;\n            this.endIdx = endIdx;\n        }\n    }\n\n    NumberRelativeTimeSuggestionHandler(Config config){\n        super(config);\n        pRel = Pattern.compile(REGEX, Pattern.CASE_INSENSITIVE);\n    }\n\n    @Override\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n        Matcher m = pRel.matcher(input);\n        if (m.find()) {\n\n            int digit;\n            if (m.group(1) != null) {\n                digit = Integer.parseInt(m.group(1));\n            } else {\n                // group 2 i.e. \"next\" isn't null\n                digit = 1;\n            }\n\n            int type = -1;\n            if (m.group(2) != null) {\n                type = RelativeDayNumItem.MONTH;\n            } else if (m.group(3) != null) {\n                type = RelativeDayNumItem.MIN;\n            } else if (m.group(4) != null) {\n                type = RelativeDayNumItem.WEEK;\n            } else if (m.group(5) != null) {\n                type = RelativeDayNumItem.DAY;\n            } else if (m.group(6) != null) {\n                type = RelativeDayNumItem.HOUR;\n            }\n\n            if (type != -1) {\n                suggestionValue.appendSuggestion(SuggestionValue.RELATIVE_DAY_NUMBER,\n                        new RelativeDayNumItem(digit, type, m.start(), m.end()));\n\n                if (type == RelativeDayNumItem.HOUR || type == RelativeDayNumItem.MIN) {\n                    // ignore rest of the handlers if hour/min found\n                    return;\n                }\n            }\n        }\n        super.handle(context, input, lastToken, suggestionValue);\n    }\n\n    @Override\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        RelativeDayNumItem relNumItem = suggestionValue.getRelativeDayNumItem();\n        if (relNumItem != null) {\n            Calendar calendar = Calendar.getInstance();\n\n            boolean isPartial = false;\n            switch (relNumItem.type) {\n                case RelativeDayNumItem.DAY:\n                    isPartial = true;\n                    calendar.add(Calendar.DAY_OF_YEAR, relNumItem.value);\n                    break;\n                case RelativeDayNumItem.HOUR:\n                    calendar.add(Calendar.HOUR_OF_DAY, relNumItem.value);\n                    break;\n                case RelativeDayNumItem.MIN:\n                    calendar.add(Calendar.MINUTE, relNumItem.value);\n                    break;\n                case RelativeDayNumItem.WEEK:\n                    isPartial = true;\n                    calendar.add(Calendar.WEEK_OF_YEAR, relNumItem.value);\n                    break;\n                case RelativeDayNumItem.MONTH:\n                    isPartial = true;\n                    calendar.add(Calendar.MONTH, relNumItem.value);\n                    break;\n            }\n\n            if (relNumItem.type != RelativeDayNumItem.HOUR && relNumItem.type != RelativeDayNumItem.MIN) {\n                TimeSuggestionHandler.TimeItem timeItem = suggestionValue.getTimeItem();\n\n                if (timeItem != null) {\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n\n                    calendar.set(Calendar.HOUR_OF_DAY, hour);\n                    calendar.set(Calendar.MINUTE, mins);\n                }\n            }\n\n            if (isPartial) {\n                suggestionList.add(new SuggestionRow(DateTimeUtils.getDisplayDate(calendar, config),\n                        SuggestionRow.PARTIAL_VALUE));\n            } else {\n                suggestionList.add(new SuggestionRow(getDisplayDate(context, calendar, true),\n                        (int) (calendar.getTimeInMillis()/1000)));\n            }\n\n\n        } else {\n            super.build(context, suggestionValue, suggestionList);\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/RelativeTimeSuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * @author p-v\n */\nclass RelativeTimeSuggestionHandler extends SuggestionHandler {\n\n    private static final String REGEX = \"\\\\b(?:(tod(?:a(?:y)?)?)|(tom(?:o(?:r(?:r(?:o(?:w)?)?)?)?)?)\" +\n            \"|(day after tomorrow)|((?:ton(?:i(?:g(?:(?:h)?t)?)?)?)|(?:ton(?:i(?:t(?:e)?)?)?)))\\\\b\";\n    private Pattern pRel;\n\n    RelativeTimeSuggestionHandler(Config config) {\n        super(config);\n        pRel = Pattern.compile(REGEX, Pattern.CASE_INSENSITIVE);\n    }\n    class RelativeDayItem extends SuggestionValue.LocalItemItem {\n\n        boolean isPartial;\n\n        RelativeDayItem(int value, boolean isPartial) {\n            super(value);\n            this.isPartial = isPartial;\n        }\n    }\n\n    @Override\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n        Matcher m = pRel.matcher(input);\n        String text;\n        if (m.find()) {\n            if ((text = m.group(1)) != null) {\n                suggestionValue.appendSuggestion(SuggestionValue.RELATIVE_DAY,\n                        new RelativeDayItem(0, !\"today\".equalsIgnoreCase(text.trim())));\n            } else if ((text = m.group(2)) != null) {\n                suggestionValue.appendSuggestion(SuggestionValue.RELATIVE_DAY,\n                        new RelativeDayItem(1, !\"tomorrow\".equalsIgnoreCase(text.trim())));\n            } else if (m.group(3) != null){\n                suggestionValue.appendSuggestion(SuggestionValue.RELATIVE_DAY, new RelativeDayItem(2, false));\n            } else {\n                suggestionValue.appendSuggestion(SuggestionValue.RELATIVE_DAY, new RelativeDayItem(10, false));\n            }\n        }\n        super.handle(context, input, lastToken, suggestionValue);\n    }\n\n    @Override\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        RelativeDayItem relItem = suggestionValue.getRelDayItem();\n        if (relItem != null) {\n            SuggestionValue.LocalItemItem todItem = suggestionValue.getTodItem();\n            TimeSuggestionHandler.TimeItem timeItem = suggestionValue.getTimeItem();\n            Value timeValue = null;\n            if (todItem != null || timeItem != null) {\n                if (todItem == null) {\n                    // timeItem is not null here\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n                } else {\n                    timeValue = getTimeValue(context, todItem, timeItem);\n                }\n            }\n            // handle relative value\n            if (relItem.value == 0) {\n                // For today\n                if (timeValue == null) {\n                    if (!relItem.isPartial) {\n\n                        int afternoonTime = AFTERNOON_TIME;\n\n                        // time is not specified\n                        Calendar cal = Calendar.getInstance();\n                        int currentHourOfDay = cal.get(Calendar.HOUR_OF_DAY);\n                        int afternoonHour = afternoonTime / 60;\n                        int afternoonMins = afternoonTime % 60;\n                        int eveningHour = 12 + EVENING_TIME;\n\n                        if (currentHourOfDay < 23) {\n                            timeValue = getTimeValue(context, currentHourOfDay + 1, 0, null, null);\n                            // Current time is less than 11PM\n                            suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                                    + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                        }\n\n                        if (currentHourOfDay < afternoonHour && currentHourOfDay + 1 != afternoonHour) {\n                            timeValue = getTimeValue(context, afternoonHour, afternoonMins, null, null);\n                            suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                                    + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                        }\n\n                        if (currentHourOfDay < eveningHour && currentHourOfDay +1 != eveningHour) {\n                            timeValue = getTimeValue(context, eveningHour, 0, \"pm\", null);\n                            suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                                    + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                        }\n                    } else {\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.today), SuggestionRow.PARTIAL_VALUE));\n                    }\n                } else {\n                    Calendar cal = Calendar.getInstance();\n                    if (timeValue.value.before(cal)) {\n                        // time past increment time by 12 hours if AM/PM is not specified otherwise by 24\n                        if (timeItem.isAmPmPresent) {\n                            timeValue.value.add(Calendar.HOUR_OF_DAY, 24);\n                            suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                                    + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                        } else {\n                            timeValue.value.add(Calendar.HOUR_OF_DAY, 12);\n                            if (timeValue.value.before(cal)) {\n                                timeValue.value.add(Calendar.HOUR_OF_DAY, 12);\n                                suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                                        + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                            } else {\n                                if (cal.get(Calendar.DAY_OF_YEAR) == timeValue.value.get(Calendar.DAY_OF_YEAR)) {\n                                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                                            + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                                } else {\n                                    suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                                            + DateTimeUtils.getDisplayTime(context, timeValue.value, config), (int)(timeValue.value.getTimeInMillis()/1000)));\n                                }\n                            }\n                        }\n                    } else {\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                                + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                    }\n                }\n            } else if (relItem.value == 1) {\n                if (timeValue == null) {\n                    if (!relItem.isPartial) {\n                        int morningTime = MORNING_TIME_WEEKDAY;\n\n                        timeValue = getTimeValue(context, morningTime / 60, morningTime % 60, null, null);\n\n                        // increment a day for tomorrow\n                        timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                                + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                        int afternoonTime = AFTERNOON_TIME;\n                        timeValue = getTimeValue(context, afternoonTime / 60,  afternoonTime % 60, null, null);\n                        // increment a day for tomorrow\n                        timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                                + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                        int eveningHour = 12 + EVENING_TIME;\n                        timeValue = getTimeValue(context, eveningHour, 0, \"pm\", null);\n                        // increment a day for tomorrow\n                        timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                                + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                    } else {\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow), SuggestionRow.PARTIAL_VALUE));\n                    }\n\n                } else {\n                    // increment a day for tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                }\n            } else if (relItem.value == 2) {\n                if (timeValue == null) {\n                    int morningTime = MORNING_TIME_WEEKDAY;\n\n                    timeValue = getTimeValue(context, morningTime / 60, morningTime % 60, null, null);\n                    // increment two days for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 2);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    int afternoonTime = AFTERNOON_TIME;\n                    timeValue = getTimeValue(context, afternoonTime / 60, afternoonTime % 60, null, null);\n                    // increment two days for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 2);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    int eveningHour = 12 + EVENING_TIME;\n                    timeValue = getTimeValue(context, eveningHour, 0, \"pm\", null);\n                    // increment two days for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 2);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                } else {\n                    // increment two days for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 2);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                }\n            } else if (relItem.value == 10) {\n                if (timeValue == null) {\n                    timeValue = getTimeValue(context, 22, 0, \"pm\", null);\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                } else {\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                }\n            }\n        } else {\n            super.build(context, suggestionValue, suggestionList);\n        }\n    }\n\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/SeerFilter.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\nimport android.text.TextUtils;\nimport android.widget.Filter;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author p-v\n */\n\npublic class SeerFilter extends Filter {\n\n    public interface OnSuggestionPublishListener {\n        void onSuggestionPublish(List<SuggestionRow> suggestionList);\n    }\n\n    private InitialSuggestionHandler initialSuggestionHandler;\n\n\n    private Context context;\n    private OnSuggestionPublishListener onSuggestionPublishListener;\n\n    public SeerFilter(Context context, Config config) {\n\n        this.context = context;\n\n        // initialize all handlers\n        initialSuggestionHandler =\n                new InitialSuggestionHandler(config);\n        NumberRelativeTimeSuggestionHandler numberRelativeTimeSuggestionHandler = new NumberRelativeTimeSuggestionHandler(config);\n        RelativeTimeSuggestionHandler relativeTimeSuggestionHandler = new RelativeTimeSuggestionHandler(config);\n        DateSuggestionHandler dateSuggestionHandler = new DateSuggestionHandler(config);\n        DOWSuggestionHandler dowSuggestionHandler = new DOWSuggestionHandler(config);\n        TimeSuggestionHandler timeSuggestionHandler = new TimeSuggestionHandler(config);\n        TODSuggestionHandler todSuggestionHandler = new TODSuggestionHandler(config);\n\n        // build handler chain\n        initialSuggestionHandler.setNextHandler(numberRelativeTimeSuggestionHandler);\n        numberRelativeTimeSuggestionHandler.setNextHandler(relativeTimeSuggestionHandler);\n        relativeTimeSuggestionHandler.setNextHandler(dateSuggestionHandler);\n        dateSuggestionHandler.setNextHandler(dowSuggestionHandler);\n        dowSuggestionHandler.setNextHandler(timeSuggestionHandler);\n        timeSuggestionHandler.setNextHandler(todSuggestionHandler);\n\n        // build builder chain\n        initialSuggestionHandler.setNextBuilder(timeSuggestionHandler);\n        timeSuggestionHandler.setNextBuilder(todSuggestionHandler);\n        todSuggestionHandler.setNextBuilder(numberRelativeTimeSuggestionHandler);\n        numberRelativeTimeSuggestionHandler.setNextBuilder(relativeTimeSuggestionHandler);\n        relativeTimeSuggestionHandler.setNextBuilder(dateSuggestionHandler);\n        dateSuggestionHandler.setNextBuilder(dowSuggestionHandler);\n    }\n\n    public SeerFilter(Context context) {\n        this(context, null);\n    }\n\n    @Override\n    protected FilterResults performFiltering(CharSequence constraint) {\n        final FilterResults results = new FilterResults();\n        if (TextUtils.isEmpty(constraint)) {\n            // Return empty results.\n            return results;\n        }\n\n        String input = constraint.toString();\n        String[] splitString = input.split(\"\\\\s+\");\n\n        // Stores information about the user input\n        SuggestionValue suggestionValue = new SuggestionValue();\n\n        // Interpret user input and store values in suggestion value\n        initialSuggestionHandler.handle(context, input, splitString[splitString.length - 1],\n                suggestionValue);\n\n        List<SuggestionRow> suggestionList = new ArrayList<>(3);\n\n        // Save values in instance so `SparseArrayCompat#get` method is not\n        // called again and again in the builders\n        suggestionValue.init();\n\n        // Build suggestion list base on the user input (i.e. the suggestion value)\n        initialSuggestionHandler.build(context, suggestionValue, suggestionList);\n\n        // update result\n        results.values = suggestionList;\n        results.count = suggestionList.size();\n        return results;\n\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    protected void publishResults(CharSequence constraint, FilterResults results) {\n        List<SuggestionRow> suggestionList = null;\n        if(results != null && results.count > 0) {\n            suggestionList = (List<SuggestionRow>) results.values;\n        }\n        if (onSuggestionPublishListener != null) {\n            onSuggestionPublishListener.onSuggestionPublish(suggestionList);\n        }\n    }\n\n    public void setOnSuggestionPublishListener(OnSuggestionPublishListener onSuggestionPublishListener) {\n        this.onSuggestionPublishListener = onSuggestionPublishListener;\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/SuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\nimport android.support.annotation.NonNull;\n\nimport java.text.DateFormat;\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.Locale;\n\n/**\n * Abstract Suggestion Handler\n *\n * Has all common methods use for displaying suggestions to the user\n *\n * The module is based on COR design pattern\n *\n * @author p-v\n */\nabstract class SuggestionHandler {\n\n    private SuggestionHandler nextHandler;\n    private SuggestionHandler nextBuilder;\n    Config config;\n\n    static final int EVENING_TIME = 5;\n    static final int AFTERNOON_TIME = 14 * 60;\n    static final int MORNING_TIME_WEEKDAY = 9 * 60;\n    static final int MORNING_TIME_WEEKEND = 10 * 60;\n    static final int WEEKEND = Constants.Weekend.SATURDAY_SUNDAY;\n\n    public SuggestionHandler(Config config) {\n        if (config == null) {\n            config = new Config.ConfigBuilder().build();\n        }\n        this.config = config;\n    }\n\n    /**\n     * Sets the next handler after the current handler\n     *\n     * @param nextHandler next handler after the current handler\n     */\n    void setNextHandler(SuggestionHandler nextHandler) {\n        this.nextHandler = nextHandler;\n    }\n\n    /**\n     * Sets the next builder after the current builder\n     *\n     * @param nextBuilder next builder after the current builder\n     */\n    void setNextBuilder(SuggestionHandler nextBuilder) {\n        this.nextBuilder = nextBuilder;\n    }\n\n    /**\n     * Build the suggestion list based on the suggestion value\n     *\n     * @param context The context to use.\n     * @param suggestionValue The value used to build the suggestions.\n     * @param suggestionList The list to add suggestions to. (pass empty the first time)\n     */\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        if (nextBuilder != null) {\n            nextBuilder.build(context, suggestionValue, suggestionList);\n        }\n    }\n\n    /**\n     * Interprets the input and converts it to SuggestionValue which can be used to build the\n     * suggestion list\n     *\n     * @param context The context to use.\n     * @param input User input.\n     * @param lastToken Last token of the user input.\n     * @param suggestionValue The value where all the related values are stored based on input (pass\n     *                        empty the first time)\n     */\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n        if (nextHandler != null) {\n            nextHandler.handle(context, input, lastToken, suggestionValue);\n        }\n    }\n\n    /**\n     * Get time Value for the time passed\n     *\n     * @param context The context to use\n     * @param hour Hour\n     * @param mins Minutes\n     * @param amPm am/pm String\n     *\n     * @return value which has display value and the real value\n     */\n    final Value getTimeValue(Context context, int hour, int mins, String amPm, Calendar value) {\n\n        if (value == null) {\n            value = Calendar.getInstance();\n        }\n\n        if (hour > 12) {\n            if (amPm != null) {\n                value.set(Calendar.HOUR_OF_DAY, hour);\n                value.set(Calendar.MINUTE, mins);\n                value.set(Calendar.SECOND, 0);\n                value.set(Calendar.MILLISECOND, 0);\n                String displayValue = DateTimeUtils.getDisplayTime(context, value, config);\n                return new Value(displayValue, value);\n            } else {\n                value.set(Calendar.HOUR, hour % 12);\n                value.set(Calendar.MINUTE, mins);\n                value.set(Calendar.SECOND, 0);\n                value.set(Calendar.MILLISECOND, 0);\n                value.set(Calendar.AM_PM, Calendar.PM);\n                String displayValue = DateTimeUtils.getDisplayTime(context, value, config);\n                return new Value(displayValue, value);\n            }\n        } else if (hour < 12) {\n            if (amPm != null) {\n                value.set(Calendar.HOUR, hour);\n                value.set(Calendar.MINUTE, mins);\n                value.set(Calendar.SECOND, 0);\n                value.set(Calendar.MILLISECOND, 0);\n                value.set(Calendar.AM_PM, \"pm\".equals(amPm) ? Calendar.PM : Calendar.AM);\n                String displayValue = DateTimeUtils.getDisplayTime(context, value, config);\n                return new Value(displayValue, value);\n            } else {\n                value.set(Calendar.HOUR, hour % 12);\n                value.set(Calendar.MINUTE, mins);\n                value.set(Calendar.SECOND, 0);\n                value.set(Calendar.MILLISECOND, 0);\n                value.set(Calendar.AM_PM, Calendar.AM);\n                String displayValue = DateTimeUtils.getDisplayTime(context, value, config);\n                return new Value(displayValue, value);\n            }\n        } else {\n            // 12 am/pm case\n            if (amPm != null) {\n                value.set(Calendar.HOUR_OF_DAY, hour);\n                value.set(Calendar.MINUTE, mins);\n                value.set(Calendar.SECOND, 0);\n                value.set(Calendar.MILLISECOND, 0);\n                String displayValue = DateTimeUtils.getDisplayTime(context, value, config);\n                return new Value(displayValue, value);\n            } else {\n                value.set(Calendar.HOUR, hour % 12);\n                value.set(Calendar.MINUTE, mins);\n                value.set(Calendar.SECOND, 0);\n                value.set(Calendar.MILLISECOND, 0);\n                value.set(Calendar.AM_PM, Calendar.PM);\n                String displayValue = DateTimeUtils.getDisplayTime(context, value, config);\n                return new Value(displayValue, value);\n            }\n        }\n    }\n\n    /**\n     *\n     * Get time Value for the time/tod item passed\n     *\n     * Time of day item should never be null\n     *\n     * @param context The context to use\n     * @param todItem Time of day item\n     * @param timeItem Time item\n     * @return return the Value having display and real value\n     */\n    final Value getTimeValue(@NonNull Context context, @NonNull SuggestionValue.LocalItemItem todItem, TimeSuggestionHandler.TimeItem timeItem) {\n        Value value = null;\n        switch (todItem.value) {\n\n            // Morning\n            case TODSuggestionHandler.TOD_MORNING:\n                if (timeItem == null) {\n                    Calendar cal = Calendar.getInstance();\n                    if (DateTimeUtils.isWeekend(cal.get(Calendar.DAY_OF_WEEK), WEEKEND)) {\n                        int morningTime = MORNING_TIME_WEEKEND;\n                        int hour = morningTime / 60;\n                        int mins = morningTime % 60;\n                        value = getTimeValue(context, hour, mins, null, null);\n                    } else {\n                        int morningTime = MORNING_TIME_WEEKDAY;\n                        int hour = morningTime / 60;\n                        int mins = morningTime % 60;\n                        value = getTimeValue(context, hour, mins, null, null);\n                    }\n                } else {\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n\n                    if (hour < 12) {\n                        value = getTimeValue(context, hour, mins, \"am\", null);\n                    } else {\n                        value = getTimeValue(context, hour, mins, \"pm\", null);\n                    }\n                }\n                break;\n\n            // Afternoon\n            case TODSuggestionHandler.TOD_AFTERNOON:\n                if (timeItem == null) {\n                    int afternoonTime = AFTERNOON_TIME;\n                    int hour = afternoonTime / 60;\n                    int mins = afternoonTime % 60;\n                    value = getTimeValue(context, hour, mins, null, null);\n                } else {\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n                    value = getTimeValue(context, hour, mins, \"pm\", null);\n                }\n                break;\n\n            // Evening\n            case TODSuggestionHandler.TOD_EVENING:\n                if (timeItem == null) {\n                    value = getTimeValue(context, EVENING_TIME, 0, \"pm\", null);\n                } else {\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n                    value = getTimeValue(context, hour, mins, \"pm\", null);\n                }\n                break;\n\n            // Night\n            case TODSuggestionHandler.TOD_NIGHT:\n                if (timeItem == null) {\n                    int nightTime = 10;\n                    value = getTimeValue(context, nightTime, 0, \"pm\", null);\n                } else {\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n                    int modHour = hour % 12;\n                    if (modHour >=0 && modHour < 4){\n                        value = getTimeValue(context, hour, mins, \"am\", null);\n                    } else if (modHour >= 4 && modHour <= 6){\n                        value = getTimeValue(context, 9, mins, \"pm\", null);\n                    } else {\n                        value = getTimeValue(context, hour, mins, \"pm\", null);\n                    }\n                }\n                break;\n\n            default:\n                break;\n\n        }\n        return value;\n    }\n\n    /**\n     * Get the display string to be shown in the suggestions\n     *\n     * @param context The context to use\n     * @param cal Calendar object to update\n     * @param isRelative Is the time relative to the current time\n     * @return Display string\n     */\n    final String getDisplayDate(Context context, Calendar cal,  boolean isRelative) {\n        if (isRelative) {\n            int days = DateTimeUtils.daysBetween(Calendar.getInstance(), cal);\n            if (days == 0) {\n                return context.getString(R.string.today) + \", \"\n                        + DateTimeUtils.getDisplayTime(context, cal, config);\n            } else if (days == 1) {\n                return context.getString(R.string.tomorrow) + \", \"\n                        + DateTimeUtils.getDisplayTime(context, cal, config);\n            } else {\n                return getDisplayDate(cal) + \", \" + DateTimeUtils.getDisplayTime(context, cal, config);\n            }\n        } else {\n            return getDisplayDate(cal);\n        }\n    }\n\n    final String getDisplayDate(Context context, Calendar cal,  String timeString) {\n        int days = DateTimeUtils.daysBetween(Calendar.getInstance(), cal);\n        if (days == 0) {\n            return context.getString(R.string.today) + \", \" + timeString;\n        } else if (days == 1) {\n            return context.getString(R.string.tomorrow) + \", \" + timeString;\n        } else {\n            return getDisplayDate(cal) + \", \" + timeString;\n        }\n    }\n\n    /**\n     * Get display date string from calendar in \"EEEE, dd MMM\" format,\n     * <br/>e.g. Mon, 12 Dec <br/> Tue, 20 Jul\n     *\n     * @param cal Calendar to use\n     * @return the display value\n     */\n    final String getDisplayDate(Calendar cal) {\n        if (Calendar.getInstance().get(Calendar.YEAR) == cal.get(Calendar.YEAR)) {\n            DateFormat df = new SimpleDateFormat(config.getDateFormatWithoutYear(), Locale.ENGLISH);\n            return df.format(cal.getTime());\n        } else {\n            DateFormat df = new SimpleDateFormat(config.getDateFormatWithYear(), Locale.ENGLISH);\n            return df.format(cal.getTime());\n        }\n    }\n\n    /**\n     * Class used internally with all the handlers\n     * to build and show suggestions\n     */\n    protected class Value {\n\n        String displayString;\n        public Calendar value;\n\n        public Value(String displayString, Calendar value) {\n            this.displayString = displayString;\n            this.value = value;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/SuggestionRow.java",
    "content": "package com.pv.datetimeseer;\n\n/**\n * @author p-v\n */\n\npublic class SuggestionRow {\n\n    public static final int PARTIAL_VALUE = -999;\n\n    private String displayValue;\n    /**\n     * Time in\n     */\n    private int value;\n\n    public SuggestionRow(String displayValue, int value) {\n        this.displayValue = displayValue;\n        this.value = value;\n    }\n\n    /**\n     * Use this to get more results when the value is set to PARTIAL_VALUE.\n     *\n     * @return the display value. <br>\n     *\n     */\n    public String getDisplayValue() {\n        return displayValue;\n    }\n\n    /**\n     *\n     * @return the time in seconds\n     */\n    public int getValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/SuggestionValue.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.support.v4.util.SparseArrayCompat;\n\n/**\n * Values regarding the user input\n *\n * @author p-v\n */\nclass SuggestionValue extends SparseArrayCompat<SuggestionValue.LocalItemItem> {\n\n    static final int RELATIVE_DAY = 0x01;\n    static final int DAY_OF_WEEK = 0x02;\n    static final int TIME_OF_DAY = 0x04;\n    static final int MONTH = 0x08;\n    static final int NUMBER = 0x10;\n    static final int TIME = 0x20;\n    static final int DATE = 0x40;\n    static final int DAY_OF_WEEK_NEXT = 0x80;\n    static final int RELATIVE_DAY_NUMBER = 0x0100;\n    static final int OTHER = 0x0200;\n\n    private TimeSuggestionHandler.TimeItem timeItem;\n    private LocalItemItem todItem;\n    private RelativeTimeSuggestionHandler.RelativeDayItem relDayItem;\n    private NumberRelativeTimeSuggestionHandler.RelativeDayNumItem relativeDayNumItem;\n    private LocalItemItem dowItem;\n    private LocalItemItem nextDowItem;\n    private LocalItemItem monthItem;\n    private DateSuggestionHandler.DateItem dateItem;\n    private LocalItemItem numberItem;\n    private LocalItemItem otherItem;\n\n    void init() {\n        relDayItem = (RelativeTimeSuggestionHandler.RelativeDayItem) this.get(RELATIVE_DAY);\n        relativeDayNumItem = (NumberRelativeTimeSuggestionHandler.RelativeDayNumItem) this.get(RELATIVE_DAY_NUMBER);\n        dowItem = this.get(DAY_OF_WEEK);\n        nextDowItem = this.get(DAY_OF_WEEK_NEXT);\n        monthItem = this.get(MONTH);\n        dateItem = (DateSuggestionHandler.DateItem) this.get(DATE);\n        todItem = this.get(TIME_OF_DAY);\n        timeItem = (TimeSuggestionHandler.TimeItem) this.get(TIME);\n        numberItem = this.get(NUMBER);\n        otherItem = this.get(OTHER);\n    }\n\n    public void appendSuggestion(int flag, int value) {\n        super.append(flag, new LocalItemItem(value));\n    }\n\n    public void appendSuggestion(int flag, LocalItemItem item) {\n        super.append(flag, item);\n    }\n\n    public static class LocalItemItem {\n\n        public int value;\n\n        public LocalItemItem(int value) {\n            this.value = value;\n        }\n\n    }\n\n    public TimeSuggestionHandler.TimeItem getTimeItem() {\n        return timeItem;\n    }\n\n    public LocalItemItem getTodItem() {\n        return todItem;\n    }\n\n    public RelativeTimeSuggestionHandler.RelativeDayItem getRelDayItem() {\n        return relDayItem;\n    }\n\n    public LocalItemItem getDowItem() {\n        return dowItem;\n    }\n\n    public LocalItemItem getNextDowItem() {\n        return nextDowItem;\n    }\n\n    public LocalItemItem getMonthItem() {\n        return monthItem;\n    }\n\n    public DateSuggestionHandler.DateItem getDateItem() {\n        return dateItem;\n    }\n\n    public NumberRelativeTimeSuggestionHandler.RelativeDayNumItem getRelativeDayNumItem() {\n        return relativeDayNumItem;\n    }\n\n    public LocalItemItem getNumberItem() {\n        return numberItem;\n    }\n\n    public LocalItemItem getOtherItem() {\n        return otherItem;\n    }\n\n\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/TODSuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * @author p-v\n */\nclass TODSuggestionHandler extends SuggestionHandler {\n\n    static final int TOD_MORNING = 1;\n    static final int TOD_AFTERNOON = 2;\n    static final int TOD_EVENING = 3;\n    static final int TOD_NIGHT = 4;\n\n    private static final String REGEX = \"\\\\b(?:(morn(?:i(?:n(?:g)?)?)?)|(after(?=(?:\\\\S+|$))(?:n(?:o(?:o(?:n)?)?)?)?)|(even(?:i(?:n(?:g)?)?)?)|(ni(?:g(?:h(?:t)?)?)?))\\\\b\";\n    private Pattern pTod;\n\n    TODSuggestionHandler(Config config) {\n        super(config);\n        pTod = Pattern.compile(REGEX, Pattern.CASE_INSENSITIVE);\n    }\n\n    @Override\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n        Matcher matcher = pTod.matcher(input);\n        if (matcher.find()) {\n            int value;\n            if (matcher.group(1) != null) {\n                value = TOD_MORNING;\n            } else if (matcher.group(2) != null) {\n                value = TOD_AFTERNOON;\n            } else if(matcher.group(3) != null) {\n                value = TOD_EVENING;\n            } else {\n                value = TOD_NIGHT;\n            }\n            suggestionValue.appendSuggestion(SuggestionValue.TIME_OF_DAY, value);\n        }\n        super.handle(context, input, lastToken, suggestionValue);\n    }\n\n    @Override\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        SuggestionValue.LocalItemItem relItem = suggestionValue.getRelDayItem();\n        SuggestionValue.LocalItemItem dowItem = suggestionValue.getDowItem();\n        SuggestionValue.LocalItemItem nextDowItem = suggestionValue.getNextDowItem();\n        SuggestionValue.LocalItemItem monthItem = suggestionValue.getMonthItem();\n        SuggestionValue.LocalItemItem dateItem = suggestionValue.getDateItem();\n        TimeSuggestionHandler.TimeItem timeItem = suggestionValue.getTimeItem();\n        NumberRelativeTimeSuggestionHandler.RelativeDayNumItem\n                relNumItem = suggestionValue.getRelativeDayNumItem();\n        SuggestionValue.LocalItemItem todItem = suggestionValue.getTodItem();\n\n        // Ignoring time timeItem. Using it later in the method\n        boolean hasOnlyTime = relItem == null && dowItem == null && nextDowItem == null &&\n                monthItem == null && dateItem == null && relNumItem == null && todItem != null;\n\n        if (hasOnlyTime) {\n            Value timeValue = getTimeValue(context, todItem, timeItem);\n            if (timeValue != null) {\n                if (timeItem == null || !timeItem.isAmPmPresent) {\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    // increment a day for tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    // increment a day for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                } else {\n                    // Time present with AM/PM\n                    int hour = timeItem.value / 60;\n                    int mins = timeItem.value % 60;\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    // increment a day for tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    // increment a day for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                }\n            }\n        } else {\n            super.build(context, suggestionValue, suggestionList);\n        }\n\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/pv/datetimeseer/TimeSuggestionHandler.java",
    "content": "package com.pv.datetimeseer;\n\nimport android.content.Context;\n\nimport java.util.Calendar;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Suggestion handler for handling time information.<br/>\n * Handles strings like 6:30, 6 40, 3pm etc.\n *\n * @author p-v\n */\nclass TimeSuggestionHandler extends SuggestionHandler {\n\n    private static final String TIME_RGX = \"\\\\b((?:2[0-3])|(?:1\\\\d)|(?:0?\\\\d))(?:(?::|\\\\s)((?:0?\\\\d)|(?:[0-5][0-9]?)))?\\\\s{0,2}([ap](?:\\\\.?m\\\\.?)?)?\\\\b\";\n    private Pattern timePattern;\n\n    /**\n     * Time item class.\n     */\n    class TimeItem extends SuggestionValue.LocalItemItem {\n\n        boolean isAmPmPresent;\n\n        TimeItem(int value, boolean amPmPresent) {\n            super(value);\n            this.isAmPmPresent = amPmPresent;\n        }\n    }\n\n    TimeSuggestionHandler(Config config) {\n        super(config);\n        timePattern = Pattern.compile(TIME_RGX, Pattern.CASE_INSENSITIVE);\n    }\n\n    @Override\n    public void handle(Context context, String input, String lastToken, SuggestionValue suggestionValue) {\n\n        DateSuggestionHandler.DateItem dateSuggestion =\n                (DateSuggestionHandler.DateItem) suggestionValue.get(SuggestionValue.DATE);\n        NumberRelativeTimeSuggestionHandler.RelativeDayNumItem numItem =\n                (NumberRelativeTimeSuggestionHandler.RelativeDayNumItem) suggestionValue.get(SuggestionValue.RELATIVE_DAY_NUMBER);\n\n        StringBuilder builder = new StringBuilder(input);\n        if (numItem != null) {\n            builder.replace(numItem.startIdx, numItem.endIdx, \"\");\n        } else if (dateSuggestion != null) {\n            builder.replace(dateSuggestion.startIdx, dateSuggestion.endIdx, \"\");\n        }\n\n        Matcher matcher = timePattern.matcher(builder.toString());\n\n        while (matcher.find()) {\n            int hourOfDay = Integer.parseInt(matcher.group(1));\n            int mins = 0;\n            String minsStr = matcher.group(2);\n            String amPm = matcher.group(3);\n\n            if (minsStr != null) {\n                mins = Integer.parseInt(minsStr);\n            }\n            if (hourOfDay < 12) {\n                if (amPm != null && amPm.matches(\"(?i)^p.*\")) {\n                    hourOfDay = hourOfDay + 12;\n                }\n            } else if (hourOfDay == 12) {\n                if (amPm != null && amPm.matches(\"(?i)^a.*\")) {\n                    hourOfDay = 0;\n                }\n            }\n            int minsInDay = hourOfDay * 60 + mins;\n\n            suggestionValue.appendSuggestion(SuggestionValue.TIME, new TimeItem(minsInDay, amPm != null));\n        }\n\n        super.handle(context, input, lastToken, suggestionValue);\n    }\n\n    @Override\n    public void build(Context context, SuggestionValue suggestionValue, List<SuggestionRow> suggestionList) {\n        SuggestionValue.LocalItemItem relItem = suggestionValue.getRelDayItem();\n        SuggestionValue.LocalItemItem dowItem = suggestionValue.getDowItem();\n        SuggestionValue.LocalItemItem nextDowItem = suggestionValue.getNextDowItem();\n        SuggestionValue.LocalItemItem monthItem = suggestionValue.getMonthItem();\n        SuggestionValue.LocalItemItem dateItem = suggestionValue.getDateItem();\n        SuggestionValue.LocalItemItem todItem = suggestionValue.getTodItem();\n        SuggestionValue.LocalItemItem relItemNum = suggestionValue.getRelativeDayNumItem();\n\n        TimeItem timeItem = suggestionValue.getTimeItem();\n\n        boolean hasOnlyTime = relItem == null && dowItem == null && nextDowItem == null &&\n                monthItem == null && dateItem == null && todItem == null && relItemNum == null\n                && timeItem != null;\n\n        if (hasOnlyTime) {\n            Value timeValue;\n            int hour = timeItem.value / 60;\n            int mins = timeItem.value % 60;\n\n            Calendar cal = Calendar.getInstance();\n            final int currentHourOfDay = cal.get(Calendar.HOUR_OF_DAY);\n            final int currentMinsOfHour = cal.get(Calendar.MINUTE);\n\n            if (timeItem.isAmPmPresent) {\n                timeValue = getTimeValue(context, hour, mins, null, null);\n                if (!(currentHourOfDay > hour || currentHourOfDay == hour && currentMinsOfHour > mins)) {\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                }\n\n                // increment a day for tomorrow\n                timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                        + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                // increment a day for day after tomorrow\n                timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value)+ \", \"\n                        + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n            } else {\n                // if the current time is more than the entered time\n                if (currentHourOfDay > hour || currentHourOfDay == hour && currentMinsOfHour > mins) {\n\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n\n                    int calculatedHourForToday = timeValue.value.get(Calendar.HOUR_OF_DAY);\n                    int calculatedMinsForToday = timeValue.value.get(Calendar.MINUTE);\n                    // Check if the calculated time for today has past\n                    if (calculatedHourForToday > currentHourOfDay ||\n                            calculatedHourForToday == currentHourOfDay && calculatedMinsForToday > currentMinsOfHour) {\n                        suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                                + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                    }\n                    // increment a day for tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    // increment a day for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value)+ \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                } else {\n                    timeValue = getTimeValue(context, hour, mins, null, null);\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.today) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    // increment a day for tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n\n                    suggestionList.add(new SuggestionRow(context.getString(R.string.tomorrow) + \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n\n                    // increment a day for day after tomorrow\n                    timeValue.value.add(Calendar.DAY_OF_YEAR, 1);\n                    suggestionList.add(new SuggestionRow(getDisplayDate(timeValue.value)+ \", \"\n                            + timeValue.displayString, (int)(timeValue.value.getTimeInMillis()/1000)));\n                }\n            }\n        } else {\n            super.build(context, suggestionValue, suggestionList);\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">DateTimeSeer</string>\n    <string name=\"today\">Today</string>\n    <string name=\"tomorrow\">Tomorrow</string>\n    <string name=\"month_ago_singular\">1 month ago</string>\n    <string name=\"month_ago_plural\">%d months ago</string>\n    <string name=\"year_ago_singular\">1 year ago</string>\n    <string name=\"year_ago_plural\">%d years ago</string>\n    <string name=\"hours_plural\">%d hours</string>\n    <string name=\"hour_singular\">%d hour</string>\n    <string name=\"minutes_plural\">%d minutes</string>\n    <string name=\"minute_singular\">%d minute</string>\n    <string name=\"day_singular\">1 day</string>\n    <string name=\"days_plural\">%d days</string>\n</resources>\n"
  },
  {
    "path": "library/src/test/java/com/pv/datetimeseer/ExampleUnitTest.java",
    "content": "package com.pv.datetimeseer;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app', ':library'\n"
  }
]