text:
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ParallelListComp #-}

module Language.K3.Codegen.CPP.Declaration where

import Control.Arrow ((&&&))
import Control.Applicative
import Control.Monad.State

import Data.Maybe

import qualified Data.List as L
import qualified Data.Map as M

import Language.K3.Core.Annotation
import Language.K3.Core.Annotation.Syntax
import Language.K3.Core.Common
import Language.K3.Core.Declaration
import Language.K3.Core.Expression
import Language.K3.Core.Type

import qualified Language.K3.Core.Constructor.Declaration as D
import qualified Language.K3.Core.Constructor.Type as T

import Language.K3.Codegen.CPP.Expression
import Language.K3.Codegen.CPP.Primitives
import Language.K3.Codegen.CPP.Types

import Language.K3.Codegen.CPP.Materialization.Hints

import qualified Language.K3.Codegen.CPP.Representation as R

import Language.K3.Utils.Pretty

-- Builtin names to explicitly skip.
skip_builtins :: [String]
skip_builtins = ["hasRead", "doRead", "doBlockRead", "hasWrite", "doWrite"]

declaration :: K3 Declaration -> CPPGenM [R.Definition]
declaration (tna -> ((DGlobal n (tnc -> (TSource, [t])) _), as)) = return []

-- Sinks with a valid body are handled in the same way as triggers.
declaration d@(tna -> (DGlobal i (tnc -> (TSink, [t])) (Just e), as)) = do
  declaration $ D.global i (T.function t T.unit) $ Just e

declaration (tag -> DGlobal i (tag -> TSink) Nothing) =
  throwE $ CPPGenE $ unwords ["Invalid sink trigger", i, "(missing body)"]

-- Global functions without implementations -- Built-Ins.
declaration (tag -> DGlobal name t@(tag -> TFunction) Nothing)
  | name `elem` skip_builtins = return []
  | any (`L.isSuffixOf` name) source_builtins = genSourceBuiltin t name >>= return . replicate 1
  | otherwise = return []

-- Global polymorphic functions without implementations -- Built-Ins
declaration (tag -> DGlobal _ (tag &&& children -> (TForall _, [tag &&& children -> (TFunction, [_, _])]))
                        Nothing) = return []

-- Global monomorphic function with direct implementations.
declaration (tag -> DGlobal i t@(tag &&& children -> (TFunction, [ta, tr]))
                      (Just e@(tag &&& children -> (ELambda x, [body]))))
  | i == "processRole" = do
      ([], R.Lambda _ mits _ _ body) <- inline e
      return $ [R.FunctionDefn (R.Name i) [(Nothing, R.Reference $ R.Const $ R.Unit)] (Just R.Unit) [] True body]
  | otherwise = do
      ([], e') <- inline e
      ct <- R.flattenFnType <$> genCType t
      return [R.GlobalDefn $ R.Forward $ R.ScalarDecl (R.Name i) ct $ Just e']

-- Global polymorphic functions with direct implementations.
declaration (tag -> DGlobal i (tag &&& children -> (TForall _, [tag &&& children -> (TFunction, [ta, tr])]))
                      (Just e@(tag &&& children -> (ELambda x, [body])))) = do

    returnType <- genCInferredType tr
    (argumentType, template) <- case tag ta of
                      TDeclaredVar t -> return (R.Named (R.Name t), Just t)
                      _ -> genCType ta >>= \cta -> return (cta, Nothing)

    let templatize = maybe id (\t -> R.TemplateDefn [(t, Nothing)]) template

    addForward $ maybe id (\t -> R.TemplateDecl [(t, Nothing)]) template $
                   R.FunctionDecl (R.Name i) [argumentType] returnType

    -- mtrlzns <- case e @~ isEMaterialization of
    --              Just (EMaterialization ms) -> return ms
    --              Nothing -> return $ M.fromList [(x, defaultDecision)]

    let argMtrlznType = case getInMethodFor x e of
                          ConstReferenced -> R.Reference (R.Const argumentType)
                          Referenced -> R.Reference argumentType
                          Forwarded -> R.RValueReference argumentType
                          _ -> argumentType

    body' <- reify (RReturn False) body
    return [templatize $ R.FunctionDefn (R.Name i) [(Just x, argMtrlznType)] (Just returnType) [] False body']

-- Global scalars.
declaration d@(tag -> DGlobal i t me) = do
    globalType <- genCType t
    let pinned = isJust $ d @~ (\case { DProperty (dPropertyV -> ("Pinned", Nothing)) -> True; _ -> False })
    let globalType' = if pinned then R.Static globalType else globalType

    -- Need to declare static members outside of class scope
    let staticGlobalDecl = [R.Forward $ R.ScalarDecl
                             (R.Qualified (R.Name "__global_context") (R.Name i))
                             globalType
                             Nothing
                           | pinned]

    addStaticDeclaration staticGlobalDecl

    -- Initialize the variable.
    let rName = RName (R.Variable $ R.Name $ if pinned then "__global_context::" ++ i else i) Nothing
    globalInit <- maybe (return []) (liftM (addSetCheck pinned i) . reify rName) me

    -- Add to proper initialization list
    let addFn = if pinned then addStaticInitialization else addGlobalInitialization
    addFn globalInit

    -- Add any annotation to the state
    when (tag t == TCollection) $ addComposite (namedTAnnotations $ annotations t) (head $ children t)

    -- Return the class-scope-declaration including the set variable if needed
    let setOp = if False then [] else
                  [R.GlobalDefn $ R.Forward $ R.ScalarDecl
                    (R.Name $ setName i) (R.Primitive R.PBool) (Just $ R.Literal $ R.LBool False)]

    return $ (R.GlobalDefn $ R.Forward $ R.ScalarDecl (R.Name i) globalType' Nothing):setOp
      where
        setName n = "__"++n++"_set__"
        addSetCheck pinned n f = if pinned then f else
          [R.IfThenElse
            (R.Unary "!" $ R.Variable $ R.Name $ setName n)
            (f ++ [R.Assignment (R.Variable $ R.Name $ setName n) (R.Literal $ R.LBool True)])
            []]

-- Triggers are implementationally identical to functions returning unit, except they also generate
-- dispatch wrappers.
declaration (tag -> DTrigger i t e) = declaration (D.global i (T.function t T.unit) (Just e))
declaration (tag -> DDataAnnotation i _ amds) = addAnnotation i amds >> return []
declaration (tag -> DRole _) = throwE $ CPPGenE "Roles below top-level are deprecated."
declaration _ = return []

-- Generated Builtins
-- Interface for source builtins.
-- Map special builtin suffix to a function that will generate the builtin.
-- These suffixes are taken from L.K3.Parser.ProgramBuilder.hs
source_builtin_map :: [(String, (String -> K3 Type -> String -> CPPGenM R.Definition))]
source_builtin_map = [("MuxHasRead",   genHasRead True     Nothing),
                      ("MuxRead",      genDoRead  True     Nothing),
                      ("PDataHasRead", genHasRead True     Nothing),
                      ("PDataRead",    genDoRead  True     Nothing),
                      ("POrdHasRead",  genHasRead False  $ Just "order"),
                      ("POrdRead",     genDoRead  False  $ Just "order"),
                      ("HasRead",      genHasRead False    Nothing),
                      ("Read",         genDoRead  False    Nothing),
                      ("HasWrite",     genHasWrite),
                      ("Write",        genDoWrite)]
                     ++ extraSuffixes

        -- These suffixes are for data loading hacks.
	-- TODO this needs refactoring, big time
  where extraSuffixes = [("Loader",       genLoader False False False False False False ","),
                         ("LoaderC",      genLoader False False True  False False False ","),
                         ("LoaderF",      genLoader False True  False False False False ","),
                         ("LoaderFC",     genLoader False True  True  False False False ","),
                         ("LoaderE",      genLoader True  False False False False False ","),
                         ("LoaderP",      genLoader False False False False False False "|"),
                         ("LoaderPC",     genLoader False False True  False False False "|"),
                         ("LoaderPF",     genLoader False True  False False False False "|"),
                         ("LoaderPFC",    genLoader False True  True  False False False "|"),
                         ("LoaderRP",     genLoader False False False True  False False "|"),
                         ("LoaderPE",     genLoader True  False False False False False "|"),
                         ("LoaderMPC",    genLoader False False True  False True  False "|"),
                         ("LoaderMosaic", genLoader False False False False False True  "|"),
                         ("Logger",    genLogger)]

source_builtins :: [String]
source_builtins = map fst source_builtin_map

stripSuffix :: String -> String -> String
stripSuffix suffix name = maybe (error "not a suffix!") reverse $ L.stripPrefix (reverse suffix) (reverse name)

genSourceBuiltin :: K3 Type -> Identifier -> CPPGenM R.Definition
genSourceBuiltin typ name = do
    suffix <- return $ head $ filter (\y -> y `L.isSuffixOf` name) source_builtins
    f <- return $ getSourceBuiltin suffix
    f typ name

-- Grab the generator function from the map, currying the key of the builtin to be generated.
getSourceBuiltin :: String -> K3 Type -> String -> CPPGenM R.Definition
getSourceBuiltin k =
    case filter (\(x,_) -> k == x) source_builtin_map of
        []         -> error $ "Could not find builtin with name" ++ k
        ((_,f):_) -> f k

genHasRead :: Bool -> Maybe String -> String -> K3 Type -> String -> CPPGenM R.Definition
genHasRead asMux chanIdSuffixOpt suf _ name = do
    concatOp        <- binarySymbol OConcat
    let source_name = stripSuffix suf name
    let e_has_r     = R.Variable $ R.Name "hasRead"
    let source_pfx  = source_name ++ if asMux || isJust chanIdSuffixOpt then "_" else ""

    let chan_id_e   = case (chanIdSuffixOpt, asMux) of
                        (Just chan_suf, _) -> R.Literal $ R.LString $ source_pfx ++ chan_suf

                        (Nothing, True) -> R.Binary concatOp (R.Literal $ R.LString source_pfx) $
                                             R.Call (R.Variable $ R.Name "itos")
                                               [R.Variable $ R.Name "muxid"]

                        (_, _) -> R.Literal $ R.LString source_pfx

    let body = R.Return $ R.Call e_has_r [R.Variable $ R.Name "me", chan_id_e]
    let args = if asMux then [(Just "muxid", R.Primitive R.PInt)]
                        else [(Just "_", R.Named $ R.Name "unit_t")]

    return $ R.FunctionDefn (R.Name name) args (Just $ R.Primitive R.PBool) [] False [body]

genDoRead :: Bool -> Maybe String -> String -> K3 Type -> String -> CPPGenM R.Definition
genDoRead asMux chanIdSuffixOpt suf typ name = do
    concatOp <- binarySymbol OConcat
    ret_type <- genCType $ last $ children typ
    let source_name = stripSuffix suf name
    let source_pfx  = source_name ++ if asMux || isJust chanIdSuffixOpt then "_" else ""

    let chan_id_e   = case (chanIdSuffixOpt, asMux) of
                        (Just chan_suf, _) -> R.Literal $ R.LString $ source_pfx ++ chan_suf

                        (Nothing, True) -> R.Binary concatOp (R.Literal $ R.LString source_pfx) $
                                             R.Call (R.Variable $ R.Name "itos")
                                               [R.Variable $ R.Name "muxid"]

                        (_, _) -> R.Literal $ R.LString source_pfx

    let body = R.Return $ (R.Call (R.Variable (R.Specialized [ret_type] $ R.Name "doRead"))
                            [R.Variable $ R.Name "me", chan_id_e])

    let args = if asMux then [(Just "muxid", R.Primitive R.PInt)]
                        else [(Just "_", R.Named $ R.Name "unit_t")]

    return $ R.FunctionDefn (R.Name name) args (Just ret_type) [] False [body]

genHasWrite :: String -> K3 Type -> String -> CPPGenM R.Definition
genHasWrite suf _ name = do
    let sink_name = stripSuffix suf name
    let e_has_w = R.Variable (R.Name "hasWrite")
    let body = R.Return $ R.Call e_has_w [R.Variable $ R.Name "me", R.Literal $ R.LString sink_name]
    return $ R.FunctionDefn (R.Name $ sink_name ++ suf) [(Just "_", R.Named $ R.Name "unit_t")]
      (Just $ R.Primitive R.PBool) [] False [body]

genDoWrite :: String -> K3 Type -> String -> CPPGenM R.Definition
genDoWrite suf typ name = do
    val_type    <- genCType $ head $ children typ
    let sink_name =  stripSuffix suf name
    let write_expr = R.Call (R.Variable $ (R.Specialized [val_type] $ R.Name "doWrite"))
                            [R.Variable $ R.Name "me", R.Literal $ R.LString sink_name, R.Variable $ R.Name "v"]
    return $ R.FunctionDefn (R.Name $ sink_name ++ suf) [(Just "v", R.Reference $ R.Const val_type)]
      (Just $ R.Named $ R.Name "unit_t") [] False
      ([R.Ignore write_expr, R.Return $ R.Initialization R.Unit []])

-- TODO: Loader is not quite valid K3. The collection should be passed by indirection so we are not working with a copy
-- (since the collection is technically passed-by-value)
genLoader :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> String -> String -> K3 Type -> String -> CPPGenM R.Definition
genLoader elemWrap fixedSize projectedLoader asReturn addMeta addMultiplicity sep suf ft@(children -> [_,f]) name = do
 void (genCType ft) -- Force full type to generate potential record/collection variants.
 (colType, recType, fullRecTypeOpt) <- return $ getColType f
 cColType      <- genCType colType
 cRecType      <- genCType recType
 cfRecType     <- maybe (return Nothing) (\t -> genCType t >>= return . Just) fullRecTypeOpt
 fields        <- getRecFields recType
 fullFieldsOpt <- maybe (return Nothing) (\frt -> getRecFields frt >>= return . Just) fullRecTypeOpt
 br <- gets (boxRecords . flags)
 let bw = if br then R.Dereference else id
 let coll_name = stripSuffix suf name
 let bufferDecl = [R.Forward $ R.ScalarDecl (R.Name "tmp_buffer")
                        (R.Named $ R.Qualified (R.Name "std") (R.Name "string")) Nothing]

 let readField f t skip b = [ R.Ignore $ R.Call (R.Variable $ R.Qualified (R.Name "std") (R.Name "getline")) $
                                     [ R.Variable (R.Name "in")
                                     , R.Variable (R.Name "tmp_buffer")
                                     ] ++ [R.Literal (R.LChar sep) | not b]
                            ] ++
                            (if skip then []
                             else [ R.Assignment (R.Project (bw $ R.Variable $ R.Name "record") (R.Name f))
                                           (typeMap t $ R.Variable $ R.Name "tmp_buffer")
                                  ])

 let recordDecl = [R.Forward $ R.ScalarDecl (R.Name "record") cRecType Nothing]

 let fts = uncurry zip fields
 let fullfts = fullFieldsOpt >>= return . uncurry zip

 let ftsWSkip = maybe (map (\(x,y) -> (x, y, False)) fts)
                      (map (\(x,y) -> (x, y, (x /= "meta") && (x `notElem` (map fst fts)))))
                      fullfts

 let containerDecl = R.Forward $ R.ScalarDecl (R.Name "c2") cColType Nothing
 let container = R.Variable $ R.Name (if asReturn then "c2" else "c")

 let setMeta = R.Assignment (R.Project (bw $ R.Variable $ R.Name "record") (R.Name "meta")) (R.Call (R.Variable $ R.Name "mf") [R.Initialization R.Unit [] ])
 let setMult = R.Assignment (R.Project (R.Variable $ R.Name "record") (R.Name . last . fst $ fields)) (R.Literal $ R.LInt 1)

 let ftsToRead = if addMultiplicity then init ftsWSkip else ftsWSkip
 let recordGetLines = recordDecl
                      ++ concat [readField field ft skip False | (field, ft, skip)  <- init ftsToRead]
                      ++ (\(a,b,c) -> readField a b c True) (last ftsToRead)
		      ++ (if addMeta then [setMeta] else [])
		      ++ (if addMultiplicity then [setMult] else [])
                      ++ [R.Return $ R.Variable $ R.Name "record"]
 let extraCaptures = if addMeta then [R.RefCapture (Just ("mf", Nothing))] else []

 let readRecordFn = R.Lambda ([R.ThisCapture] ++ extraCaptures)
                    [ (Just "in", (R.Reference $ R.Named $ R.Qualified (R.Name "std") (R.Name "istream")))
                    , (Just "tmp_buffer", (R.Reference $ R.Named $ (R.Qualified (R.Name "std") (R.Name "string"))))
                    ] False Nothing recordGetLines

 let rrm = if br then (++ "_boxed") else id

 let readRecordsCall = if asReturn
                       then R.Call (R.Variable $ R.Qualified (R.Name "K3") $ R.Name $ rrm "read_records_into_container")
                              [ R.Variable $ R.Name "paths"
                              , container
                              , readRecordFn ]
                       else
                        (if fixedSize
                         then R.Call (R.Variable $ R.Qualified (R.Name "K3") $ R.Name "read_records_with_resize")
                                [ R.Variable $ R.Name "size"
                                , R.Variable $ R.Name "paths"
                                , container
                                , readRecordFn
                                ]
                         else R.Call (R.Variable $ R.Qualified (R.Name "K3") $ R.Name $ rrm "read_records")
                                [ R.Variable $ R.Name "paths"
                                , container
                                , readRecordFn
                                ])

 pathsType <- genCType ((T.collection $ T.record [("path", T.string)]) @+ TAnnotation "Collection")
 let defaultArgs = [(Just "paths", pathsType)]

 let args = defaultArgs
              ++ [(Just "c", R.Reference $ (if asReturn then R.Const else id) cColType)]
              ++ (if projectedLoader then [(Just "_rec", R.Reference $ fromJust cfRecType)] else [])
              ++ (if fixedSize       then [(Just "size", R.Primitive R.PInt)] else [])
	      ++ (if addMeta         then [(Just "mf", R.Named $ R.Name "MetaFn")] else [])

 let returnType   = if asReturn then cColType else R.Named $ R.Name "unit_t"
 let functionBody = if asReturn
                      then [ containerDecl, R.Return $ readRecordsCall ]
                      else [ R.Ignore $ readRecordsCall, R.Return $ R.Initialization R.Unit [] ]

 let defaultDefn = R.FunctionDefn (R.Name $ coll_name ++ suf) args (Just $ returnType) [] False functionBody
 return $ if addMeta then R.TemplateDefn [("MetaFn", Nothing)] defaultDefn else defaultDefn

 where
   typeMap :: K3 Type -> R.Expression -> R.Expression
   typeMap (tag &&& (@~ isTDateInt) -> (TInt, Just _)) e =
     R.Call (R.Variable $ R.Name "tpch_date") [R.Call (R.Project e (R.Name "c_str")) []]

   typeMap (tag -> TInt) e = R.Call (R.Variable $ R.Qualified (R.Name "std") (R.Name "atoi"))
                             [R.Call (R.Project e (R.Name "c_str")) []]
   typeMap (tag -> TReal) e = R.Call (R.Variable $ R.Qualified (R.Name "std") (R.Name "atof"))
                              [R.Call (R.Project e (R.Name "c_str")) []]
   typeMap (tag -> _) x = x

   isTDateInt :: Annotation Type -> Bool
   isTDateInt (TProperty (tPropertyName -> "TPCHDate")) = True
   isTDateInt _ = False

   getColType = case fnArgs [] f of
                  [c, fr, sz] | projectedLoader && fixedSize -> colRecOfType c >>= \(x,y) -> return (x, y, Just fr)
                  [c, fr]     | projectedLoader              -> colRecOfType c >>= \(x,y) -> return (x, y, Just fr)
                  [c, fr, f]  | projectedLoader              -> colRecOfType c >>= \(x,y) -> return (x, y, Just fr)
                  [c, _]      | fixedSize                    -> colRecOfType c >>= \(x,y) -> return (x, y, Nothing)
                  [c]                                        -> colRecOfType c >>= \(x,y) -> return (x, y, Nothing)
                  _                                          -> type_mismatch

   fnArgs acc t@(tnc -> (TFunction, [a,r])) = fnArgs (acc++[a]) r
   fnArgs acc _ = acc

   colRecOfType c@(tnc -> (TCollection, [r])) | elemWrap  = return (c, removeElem r)
   colRecOfType c@(tnc -> (TCollection, [r])) | otherwise = return (c, r)
   colRecOfType _ = type_mismatch

   removeElem (tag &&& children -> (TRecord [_], [inner])) = inner
   removeElem _ = error "Invalid record structure for elemLoader"

   getRecFields (tag &&& children -> (TRecord ids, cs))  = return (ids, cs)
   getRecFields _ = error "Cannot get fields for non-record type"

   type_mismatch = error "Invalid type for Loader function. Should Be String -> Collection R -> ()"

genLoader _ _ _ _ _ _ _ _ _ _ =  error "Invalid type for Loader function."

genLogger :: String -> K3 Type -> String -> CPPGenM R.Definition
genLogger _ (children -> [_,f]) name = do
  (colType, recType) <- getColType
  let (fields,_) = getRecFields recType
  let fieldLogs = map (log . proj) fields
  let allLogs = L.intersperse (seperate $ R.Variable $ R.Name "sep") fieldLogs
  cRecType <- genCType recType
  cColType <- genCType colType
  let printRecordFn = R.Lambda []
                    [ (Just "file", R.Reference $ R.Named $ R.Qualified (R.Name "std") (R.Name "ofstream"))
                    , (Just "elem", R.Reference $ R.Const cRecType)
                    , (Just "sep", R.Reference $ R.Const $ R.Named $ R.Name "string")
                    ] False Nothing (map R.Ignore allLogs)

  return $ R.FunctionDefn (R.Name name)
             [ (Just "file", R.Named $ R.Name "string")
             , (Just "c", R.Reference cColType)
             , (Just "sep", R.Reference $ R.Const $ R.Named $ R.Name "string")]
             (Just $ R.Named $ R.Name "unit_t") [] False
             [ R.Return $ R.Call (R.Variable $ R.Name "logHelper")
                            [ R.Variable $ R.Name "file"
                            , R.Variable $ R.Name "c"
                            , printRecordFn
                            , R.Variable $ R.Name "sep"
                            ]
             ]

  where
   proj i = R.Project (R.Variable $ R.Name "elem") (R.Name i)
   log = R.Binary "<<" (R.Variable $ R.Name "file")
   seperate s = log s
   getColType = case children f of
                  ([c,_])  -> case children c of
                                [r] -> return (c, r)
                                _   -> type_mismatch
                  _        -> type_mismatch

   getRecFields (tag &&& children -> (TRecord ids, cs))  = (ids, cs)
   getRecFields _ = error "Cannot get fields for non-record type"

   type_mismatch = error "Invalid type for Logger function. Must be a flat-record of ints, reals, and strings"

genLogger _ _ _ = error "Error: Invalid type for Logger function. Must be a flat-record of ints, reals, and strings"

genCsvParser :: K3 Type -> CPPGenM (Maybe R.Expression)
genCsvParser t@(tag &&& children -> (TTuple, ts)) = genCsvParserImpl t ts get >>= (return . Just)
  where
    get exp i = R.Call
               (R.Variable $ R.Qualified (R.Name "std") (R.Specialized [R.Named $ R.Name (show i)] (R.Name "get")))
               [exp]
genCsvParser t@(tag &&& children -> (TRecord ids, ts)) = genCsvParserImpl t ts project >>= (return . Just)
  where
    project exp i = R.Project exp (R.Name (ids L.!! i))
genCsvParser _ = error "Can't generate CsvParser. Only works for flat records and tuples"

genCsvParserImpl :: K3 Type -> [K3 Type] -> (R.Expression -> Int -> R.Expression) -> CPPGenM R.Expression
genCsvParserImpl elemType childTypes accessor = do
  et  <- genCType elemType
  let fields = concatMap (uncurry readField) (zip childTypes [0,1..])
  return $ R.Lambda
               []
               [(Just "str", R.Reference $ R.Const $ R.Named $ R.Qualified (R.Name "std") (R.Name "string"))]
               False
               Nothing
               ( [iss_decl, iss_str, tup_decl et, token_decl] ++ fields ++ [R.Return tup])
  where

   iss_decl = R.Forward $ R.ScalarDecl (R.Name "iss") (R.Named $ R.Qualified (R.Name "std") (R.Name "istringstream")) Nothing
   iss_str  = R.Ignore $ R.Call (R.Project iss (R.Name "str")) [R.Variable $ R.Name "str"]
   token_decl = R.Forward $ R.ScalarDecl (R.Name "token") (R.Named $ R.Qualified (R.Name "std") (R.Name "string")) Nothing
   iss = R.Variable $ R.Name "iss"
   token = R.Variable $ R.Name "token"
   tup_decl et = R.Forward $ R.ScalarDecl (R.Name "tup") et Nothing
   tup = R.Variable $ R.Name "tup"

   readField :: K3 Type -> Int -> [R.Statement]
   readField t i = [ R.Ignore getline
                   , R.Assignment (accessor tup i) (typeMap t cstr)
                   ]

   cstr = R.Call (R.Project token (R.Name "c_str")) []

   getline = R.Call
               (R.Variable $ R.Qualified (R.Name "std") (R.Name "getline"))
               [iss, token, R.Literal $ R.LChar "|"]

   typeMap :: K3 Type -> R.Expression -> R.Expression
   typeMap (tag -> TInt) e = R.Call (R.Variable $ R.Qualified (R.Name "std") (R.Name "atoi"))
                             [e]
   typeMap (tag -> TReal) e = R.Call (R.Variable $ R.Qualified (R.Name "std") (R.Name "atof"))
                              [e]
   typeMap (tag -> TString) e = R.Call (R.Variable $ R.Name "string_impl") [e]
   typeMap (tag -> _) x = x


text:
**ExternalCoreTests** is the primary test class in the [**External** project][1].

[1]: https://github.com/dalehenrich/external

redpajama_set_name: RedPajamaGithub


text:
using Poco::Util::AbstractConfiguration;
using Poco::Util::MapConfiguration;
using Poco::AutoPtr;

AbstractConfigurationTest::AbstractConfigurationTest(const std::string& name): CppUnit::TestCase(name)
{
}

AbstractConfigurationTest::~AbstractConfigurationTest()
{
}

void AbstractConfigurationTest::testHasProperty()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	assert (pConf->hasProperty("prop1"));
	assert (pConf->hasProperty("prop2"));
	assert (pConf->hasProperty("prop3.string1"));
	assert (!pConf->hasProperty("prop3.string3"));
	assert (!pConf->hasProperty("foobar"));
}

void AbstractConfigurationTest::testGetString()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	assert (pConf->getString("prop1") == "foo");
	assert (pConf->getString("prop2") == "bar");
	assert (pConf->getString("prop3.string1") == "foo");
	assert (pConf->getString("prop3.string2") == "bar");
	assert (pConf->getString("ref1") == "foobar");
	assert (pConf->getRawString("ref1") == "${prop3.string1}${prop3.string2}");

	try
	{
		std::string res = pConf->getString("foo");
		fail("nonexistent property - must throw");
	}
	catch (Poco::NotFoundException&)
	{
	}

	assert (pConf->getString("prop1", "FOO") == "foo");
	assert (pConf->getString("prop2", "BAR") == "bar");
	assert (pConf->getString("prop3.string1", "FOO") == "foo");
	assert (pConf->getString("prop3.string2", "BAR") == "bar");
	assert (pConf->getString("prop3.string3", "FOOBAR") == "FOOBAR");
}

void AbstractConfigurationTest::testGetInt()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	assert (pConf->getInt("prop4.int1") == 42);
	assert (pConf->getInt("prop4.int2") == -42);
	assert (pConf->getInt("prop4.hex") == 0x1f);
	assert (pConf->getInt("ref2") == 42);

	try
	{
		pConf->getInt("prop1");
		fail("not a number - must throw");
	}
	catch (Poco::SyntaxException&)
	{
	}

	assert (pConf->getInt("prop4.int1", 100) == 42);
	assert (pConf->getInt("prop4.int2", 100) == -42);
	assert (pConf->getInt("prop4.int3", 100) == 100);
}

void AbstractConfigurationTest::testGetDouble()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	assert (pConf->getDouble("prop4.double1") == 1);
	assert (pConf->getDouble("prop4.double2") == -1.5);

	try
	{
		pConf->getDouble("prop1");
		fail("not a number - must throw");
	}
	catch (Poco::SyntaxException&)
	{
	}

	assert (pConf->getDouble("prop4.double1", 123.5) == 1);
	assert (pConf->getDouble("prop4.double2", 123.5) == -1.5);
	assert (pConf->getDouble("prop4.double3", 123.5) == 123.5);
}

void AbstractConfigurationTest::testGetBool()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	assert (pConf->getBool("prop4.bool1"));
	assert (!pConf->getBool("prop4.bool2"));
	assert (pConf->getBool("prop4.bool3"));
	assert (!pConf->getBool("prop4.bool4"));
	assert (pConf->getBool("prop4.bool5"));
	assert (!pConf->getBool("prop4.bool6"));
	assert (pConf->getBool("prop4.bool7"));
	assert (!pConf->getBool("prop4.bool8"));

	try
	{
		pConf->getBool("prop1");
		fail("not a boolean - must throw");
	}
	catch (Poco::SyntaxException&)
	{
	}

	assert (pConf->getBool("prop4.bool1", false));
	assert (!pConf->getBool("prop4.bool2", true));
	assert (pConf->getBool("prop4.boolx", true));
	assert (!pConf->getBool("prop4.booly", false));
}

void AbstractConfigurationTest::testExpand()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	assert (pConf->getString("ref1") == "foobar");
	assert (pConf->getInt("ref2") == 42);

	try
	{
		std::string s = pConf->getString("ref3");
		fail("circular reference - must throw");
	}
	catch (Poco::CircularReferenceException&)
	{
	}

	assert (pConf->getString("ref5") == "${refx}");
	assert (pConf->getString("ref6") == "${refx}");

	assert (pConf->expand("answer=${prop4.int1}") == "answer=42");
	assert (pConf->expand("bool5='${prop4.bool5}'") == "bool5='Yes'");
	assert (pConf->expand("undef='${undef}'") == "undef='${undef}'");
	assert (pConf->expand("deep='${ref1}'") == "deep='foobar'");
	assert (pConf->expand("deep='${ref7}'") == "deep='foobar'");

	assert (pConf->getString("dollar.atend") == "foo$");
	assert (pConf->getString("dollar.middle") == "foo$bar");
}

void AbstractConfigurationTest::testSetString()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	pConf->setString("set.string1", "foobar");
	pConf->setString("set.string2", "");
	assert (pConf->getString("set.string1") == "foobar");
	assert (pConf->getString("set.string2") == "");
}

void AbstractConfigurationTest::testSetInt()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	pConf->setInt("set.int1", 42);
	pConf->setInt("set.int2", -100);
	assert (pConf->getInt("set.int1") == 42);
	assert (pConf->getInt("set.int2") == -100);
}

void AbstractConfigurationTest::testSetDouble()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	pConf->setDouble("set.double1", 1.5);
	pConf->setDouble("set.double2", -1.5);
	assert (pConf->getDouble("set.double1") == 1.5);
	assert (pConf->getDouble("set.double2") == -1.5);
}

void AbstractConfigurationTest::testSetBool()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	pConf->setBool("set.bool1", true);
	pConf->setBool("set.bool2", false);
	assert (pConf->getBool("set.bool1"));
	assert (!pConf->getBool("set.bool2"));
}

void AbstractConfigurationTest::testChangeEvents()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	pConf->propertyChanging += Poco::delegate(this, &AbstractConfigurationTest::onPropertyChanging);
	pConf->propertyChanged += Poco::delegate(this, &AbstractConfigurationTest::onPropertyChanged);

	pConf->setString("set.string1", "foobar");
	assert (_changingKey == "set.string1");
	assert (_changingValue == "foobar");
	assert (_changedKey == "set.string1");
	assert (_changedValue == "foobar");

	pConf->setInt("set.int1", 42);
	assert (_changingKey == "set.int1");
	assert (_changingValue == "42");
	assert (_changedKey == "set.int1");
	assert (_changedValue == "42");

	pConf->setDouble("set.double1", 1.5);
	assert (_changingKey == "set.double1");
	assert (_changingValue == "1.5");
	assert (_changedKey == "set.double1");
	assert (_changedValue == "1.5");

	pConf->setBool("set.bool1", true);
	assert (_changingKey == "set.bool1");
	assert (_changingValue == "true");
	assert (_changedKey == "set.bool1");
	assert (_changedValue == "true");
}

void AbstractConfigurationTest::testRemoveEvents()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	pConf->propertyRemoving += Poco::delegate(this, &AbstractConfigurationTest::onPropertyRemoving);
	pConf->propertyRemoved += Poco::delegate(this, &AbstractConfigurationTest::onPropertyRemoved);

	pConf->remove("prop4.bool1");
	assert (_removingKey == "prop4.bool1");
	assert (_removedKey == "prop4.bool1");
}

void AbstractConfigurationTest::testKeys()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();

	AbstractConfiguration::Keys keys;
	pConf->keys(keys);
	assert (keys.size() == 13);
	assert (std::find(keys.begin(), keys.end(), "prop1") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "prop2") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "prop3") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "prop4") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "ref1") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "ref2") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "ref3") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "ref4") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "ref5") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "ref6") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "ref7") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "dollar") != keys.end());

	pConf->keys("prop1", keys);
	assert (keys.empty());

	pConf->keys("prop3", keys);
	assert (keys.size() == 2);
	assert (std::find(keys.begin(), keys.end(), "string1") != keys.end());
	assert (std::find(keys.begin(), keys.end(), "string2") != keys.end());

	assert (!pConf->hasProperty("nonexistent.sub"));
	pConf->keys("nonexistent.sub", keys);
	assert (keys.empty());
}

void AbstractConfigurationTest::testRemove()
{
	AutoPtr<AbstractConfiguration> pConf = createConfiguration();
	AbstractConfiguration::Keys keys;

	assert (pConf->hasProperty("prop1"));
	assert (pConf->hasProperty("prop4.bool1"));
	assert (pConf->hasProperty("prop4.bool2"));
	assert (pConf->hasProperty("prop4.bool3"));
	pConf->keys(keys);
	assert (keys.size() == 13);
	pConf->keys("prop4", keys);
	assert (keys.size() == 13);

	pConf->remove("prop4.bool1");
	assert (!pConf->hasProperty("prop4.bool1"));
	assert (pConf->hasProperty("prop4.bool2"));
	assert (pConf->hasProperty("prop4.bool3"));
	pConf->keys(keys);
	assert (keys.size() == 13);
	pConf->keys("prop4", keys);
	assert (keys.size() == 12);

	pConf->remove("prop4");
	assert (!pConf->hasProperty("prop4.bool1"));
	assert (!pConf->hasProperty("prop4.bool2"));
	assert (!pConf->hasProperty("prop4.bool3"));
	assert (pConf->hasProperty("prop1"));
	pConf->keys(keys);
	assert (keys.size() == 12);
	pConf->keys("prop4", keys);
	assert (keys.size() == 0);

	assert (!pConf->hasProperty("nonexistent.sub.value"));
	pConf->remove("nonexistent.sub.value");
	assert (!pConf->hasProperty("nonexistent.sub.value"));
}

Poco::AutoPtr<AbstractConfiguration> AbstractConfigurationTest::createConfiguration() const
{
	Poco::AutoPtr<AbstractConfiguration> pConfig = allocConfiguration();

	pConfig->setString("prop1", "foo");
	pConfig->setString("prop2", "bar");
	pConfig->setString("prop3.string1", "foo");
	pConfig->setString("prop3.string2", "bar");
	pConfig->setString("prop4.int1", "42");
	pConfig->setString("prop4.int2", "-42");
	pConfig->setString("prop4.hex", "0x1f");
	pConfig->setString("prop4.double1", "1");
	pConfig->setString("prop4.double2", "-1.5");
	pConfig->setString("prop4.bool1", "1");
	pConfig->setString("prop4.bool2", "0");
	pConfig->setString("prop4.bool3", "True");
	pConfig->setString("prop4.bool4", "FALSE");
	pConfig->setString("prop4.bool5", "Yes");
	pConfig->setString("prop4.bool6", "no");
	pConfig->setString("prop4.bool7", "ON");
	pConfig->setString("prop4.bool8", "Off");
	pConfig->setString("prop5.string1", "foo");
	pConfig->setString("prop5.string2", "bar");
	pConfig->setString("prop5.sub1.string1", "FOO");
	pConfig->setString("prop5.sub1.string2", "BAR");
	pConfig->setString("prop5.sub2.string1", "Foo");
	pConfig->setString("prop5.sub2.string2", "Bar");
	pConfig->setString("ref1", "${prop3.string1}${prop3.string2}");
	pConfig->setString("ref2", "${prop4.int1}");
	pConfig->setString("ref3", "${ref4}");
	pConfig->setString("ref4", "${ref3}");
	pConfig->setString("ref5", "${refx}");
	pConfig->setString("ref6", "${refx");
	pConfig->setString("ref7", "${ref1}");
	pConfig->setString("dollar.atend", "foo$");
	pConfig->setString("dollar.middle", "foo$bar");

	return pConfig;
}

void AbstractConfigurationTest::setUp()
{
	_changingKey.clear();
	_changingValue.clear();
	_changedKey.clear();
	_changedValue.clear();
	_removingKey.clear();
	_removedKey.clear();
}

void AbstractConfigurationTest::tearDown()
{
}

void AbstractConfigurationTest::onPropertyChanging(const void*, AbstractConfiguration::KeyValue& kv)
{
	_changingKey   = kv.key();
	_changingValue = kv.value();
}

void AbstractConfigurationTest::onPropertyChanged(const void*, const AbstractConfiguration::KeyValue& kv)
{
	_changedKey   = kv.key();
	_changedValue = kv.value();
}

void AbstractConfigurationTest::onPropertyRemoving(const void*, const std::string& key)
{
	_removingKey = key;
}

void AbstractConfigurationTest::onPropertyRemoved(const void*, const std::string& key)
{
	_removedKey = key;
}


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
Madras J. Lit. Sci. ser. 2, 20:66. 1859

#### Original name
null

### Remarks
null


text:
<component name="libraryTable">
  <library name="com.android.support:support-core-utils-25.1.0">
    <CLASSES>
      <root url="jar://$USER_HOME$/.android/build-cache/250a944dd12c7fd8e6d8526e7489866cd3e2af27/output/jars/classes.jar!/" />
      <root url="file://$USER_HOME$/.android/build-cache/250a944dd12c7fd8e6d8526e7489866cd3e2af27/output/res" />
    </CLASSES>
    <JAVADOC>
      <root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/android/m2repository/com/android/support/support-core-utils/25.1.0/support-core-utils-25.1.0-javadoc.jar!/" />
    </JAVADOC>
    <SOURCES>
      <root url="jar://$USER_HOME$/AppData/Local/Android/Sdk/extras/android/m2repository/com/android/support/support-core-utils/25.1.0/support-core-utils-25.1.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>


text:
Andreas Mützel
==============

This is my personal page

:email: amuetzel (at) uni-koblenz.de
:project: KdTrees on GPU using CUDA
:mentor: **Marius Muja** (Stéphane Magnenat [Radu B. Rusu, Michael Dixon])

About me
--------

I'm a master's student  at the `University of Koblenz-Landau <http://www.uni-koblenz-landau.de>`_ in the Computational Visualistics program.
There, my main interests are image processing and robotics, and this is my first serious GPU programming project.

Apart from computer stuff, such as programming and games, my hobbies include playing the guitar, listening to heavy metal music and (recently) rock climbing.

Roadmap
-------

Here is a brief outline of my GSoC project milestones:

  * Get familiar with FLANN - http://www.cs.ubc.ca/~mariusm/index.php/FLANN/FLANN

    - is currently used in PCL for k-nn search and for radius-search
    - contains several index types, of special interest is the low dimensionality kd-tree index (KDTreeSingleIndex)
    - have a look at the FLANN public interface (flann::Index class), we would like the GPU implementation to use the same interface. If you think we need to change this interface in some way to allow better performance, we can discuss about it and come up with the best solution

  * KDTree on GPU

    - Get familiar with an existing kd-tree implementation on GPU: http://www.cs.unc.edu/~shawndb/
    - Benchmark against the CPU implementation and FLANN's KDTreeSingleIndex

  * 3D/4D kdtree GPU implementation in FLANN

    - Create GPU kd-tree implementation (may use lessons learned from Shanw's implementation and from the CPU implementation in FLANN)
    - Analise trade-offs and changes that a GPU implementation requires vs a CPU implementation
    - Profile the GPU implementation and the CPU implementation to understand the bottlenecks in each case
    - Document and write a tutorial on how to use the GPU implementation

  * High dimensional GPU implementation of existing FLANN algorithms

    - Is it feasible to implement any of the higher dimensional approximate nearest neighbor search algorithms from FLANN on GPU?
    - If yes, implement it and benchmark it against the CPU implementation.
    - Document and write a tutorial on how to use the GPU implementation

Click :ref:`here <amuetzel_roadmap>` for a more detailed roadmap

Recent status updates
---------------------

.. blogbody::
   :author: amuetzel
   :nr_posts: 5

.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..

.. toctree::
   :hidden:

   roadmap
   status


text:
class AddProcedureToLegislativeFileStates < ActiveRecord::Migration
  def change
    remove_column :legislative_file_states, :ref_id
    remove_column :legislative_file_states, :ref_type

    add_belongs_to :procedures, :legislative_file_state, index: true, foreign_key: true
  end
end


text:
public class ApplicationModel {

	public static string sceneToLoadName = "";
	public static string doorToArriveName = "";

}


text:
#include "config.h"
#include "ChromeClientImpl.h"

#include "ColorChooserPopupUIController.h"
#include "ColorChooserUIController.h"
#include "DateTimeChooserImpl.h"
#include "ExternalDateTimeChooser.h"
#include "ExternalPopupMenu.h"
#include "HTMLNames.h"
#include "PopupContainer.h"
#include "PopupMenuChromium.h"
#include "RuntimeEnabledFeatures.h"
#include "WebAccessibilityObject.h"
#include "WebAutofillClient.h"
#include "WebColorChooser.h"
#include "WebConsoleMessage.h"
#include "WebCursorInfo.h"
#include "WebFileChooserCompletionImpl.h"
#include "WebFrameClient.h"
#include "WebFrameImpl.h"
#include "WebInputElement.h"
#include "WebInputEvent.h"
#include "WebKit.h"
#include "WebNode.h"
#include "WebPasswordGeneratorClient.h"
#include "WebPlugin.h"
#include "WebPluginContainerImpl.h"
#include "WebPopupMenuImpl.h"
#include "WebPopupMenuInfo.h"
#include "WebPopupType.h"
#include "WebSettings.h"
#include "WebSettingsImpl.h"
#include "WebTextDirection.h"
#include "WebUserGestureIndicator.h"
#include "WebUserGestureToken.h"
#include "WebViewClient.h"
#include "WebViewImpl.h"
#include "WebWindowFeatures.h"
#include "bindings/v8/ScriptController.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/accessibility/AccessibilityObject.h"
#include "core/dom/Document.h"
#include "core/dom/Node.h"
#include "core/html/HTMLInputElement.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/loader/NavigationAction.h"
#include "core/page/Console.h"
#include "core/page/FrameView.h"
#include "core/page/Page.h"
#include "core/page/PagePopupDriver.h"
#include "core/page/Settings.h"
#include "core/page/WindowFeatures.h"
#include "core/platform/ColorChooser.h"
#include "core/platform/ColorChooserClient.h"
#include "core/platform/Cursor.h"
#include "core/platform/DateTimeChooser.h"
#include "core/platform/FileChooser.h"
#include "core/platform/PlatformScreen.h"
#include "core/platform/chromium/support/WrappedResourceRequest.h"
#include "core/platform/graphics/FloatRect.h"
#include "core/platform/graphics/GraphicsLayer.h"
#include "core/platform/graphics/IntRect.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderWidget.h"
#include "modules/geolocation/Geolocation.h"
#include "public/platform/Platform.h"
#include "public/platform/WebRect.h"
#include "public/platform/WebURLRequest.h"
#include "weborigin/SecurityOrigin.h"
#include "wtf/text/CString.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/StringConcatenate.h"
#include "wtf/unicode/CharacterNames.h"

using namespace WebCore;

namespace WebKit {

// Converts a WebCore::PopupContainerType to a WebKit::WebPopupType.
static WebPopupType convertPopupType(PopupContainer::PopupType type)
{
    switch (type) {
    case PopupContainer::Select:
        return WebPopupTypeSelect;
    case PopupContainer::Suggestion:
        return WebPopupTypeSuggestion;
    default:
        ASSERT_NOT_REACHED();
        return WebPopupTypeNone;
    }
}

// Converts a WebCore::AXObjectCache::AXNotification to a WebKit::WebAccessibilityNotification
static WebAccessibilityNotification toWebAccessibilityNotification(AXObjectCache::AXNotification notification)
{
    // These enums have the same values; enforced in AssertMatchingEnums.cpp.
    return static_cast<WebAccessibilityNotification>(notification);
}

ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView)
    : m_webView(webView)
    , m_toolbarsVisible(true)
    , m_statusbarVisible(true)
    , m_scrollbarsVisible(true)
    , m_menubarVisible(true)
    , m_resizable(true)
    , m_pagePopupDriver(webView)
{
}

ChromeClientImpl::~ChromeClientImpl()
{
}

void* ChromeClientImpl::webView() const
{
    return static_cast<void*>(m_webView);
}

void ChromeClientImpl::chromeDestroyed()
{
    // Our lifetime is bound to the WebViewImpl.
}

void ChromeClientImpl::setWindowRect(const FloatRect& r)
{
    if (m_webView->client())
        m_webView->client()->setWindowRect(IntRect(r));
}

FloatRect ChromeClientImpl::windowRect()
{
    WebRect rect;
    if (m_webView->client())
        rect = m_webView->client()->rootWindowRect();
    else {
        // These numbers will be fairly wrong. The window's x/y coordinates will
        // be the top left corner of the screen and the size will be the content
        // size instead of the window size.
        rect.width = m_webView->size().width;
        rect.height = m_webView->size().height;
    }
    return FloatRect(rect);
}

FloatRect ChromeClientImpl::pageRect()
{
    // We hide the details of the window's border thickness from the web page by
    // simple re-using the window position here.  So, from the point-of-view of
    // the web page, the window has no border.
    return windowRect();
}

void ChromeClientImpl::focus()
{
    if (m_webView->client())
        m_webView->client()->didFocus();
}

void ChromeClientImpl::unfocus()
{
    if (m_webView->client())
        m_webView->client()->didBlur();
}

bool ChromeClientImpl::canTakeFocus(FocusDirection)
{
    // For now the browser can always take focus if we're not running layout
    // tests.
    return !layoutTestMode();
}

void ChromeClientImpl::takeFocus(FocusDirection direction)
{
    if (!m_webView->client())
        return;
    if (direction == FocusDirectionBackward)
        m_webView->client()->focusPrevious();
    else
        m_webView->client()->focusNext();
}

void ChromeClientImpl::focusedNodeChanged(Node* node)
{
    m_webView->client()->focusedNodeChanged(WebNode(node));

    WebURL focusURL;
    if (node && node->isLink()) {
        // This HitTestResult hack is the easiest way to get a link URL out of a
        // WebCore::Node.
        HitTestResult hitTest(IntPoint(0, 0));
        // This cast must be valid because of the isLink() check.
        hitTest.setURLElement(toElement(node));
        if (hitTest.isLiveLink())
            focusURL = hitTest.absoluteLinkURL();
    }
    m_webView->client()->setKeyboardFocusURL(focusURL);
}

Page* ChromeClientImpl::createWindow(
    Frame* frame, const FrameLoadRequest& r, const WindowFeatures& features, const NavigationAction& action, NavigationPolicy navigationPolicy)
{
    if (!m_webView->client())
        return 0;

    WebNavigationPolicy policy = static_cast<WebNavigationPolicy>(navigationPolicy);
    if (policy == WebNavigationPolicyIgnore)
        policy = getNavigationPolicy();

    WrappedResourceRequest request;
    if (!r.resourceRequest().isEmpty())
        request.bind(r.resourceRequest());
    else if (!action.resourceRequest().isEmpty())
        request.bind(action.resourceRequest());
    WebViewImpl* newView = static_cast<WebViewImpl*>(
        m_webView->client()->createView(WebFrameImpl::fromFrame(frame), request, features, r.frameName(), policy));
    if (!newView)
        return 0;
    return newView->page();
}

static inline void updatePolicyForEvent(const WebInputEvent* inputEvent, NavigationPolicy* policy)
{
    if (!inputEvent || inputEvent->type != WebInputEvent::MouseUp)
        return;

    const WebMouseEvent* mouseEvent = static_cast<const WebMouseEvent*>(inputEvent);

    unsigned short buttonNumber;
    switch (mouseEvent->button) {
    case WebMouseEvent::ButtonLeft:
        buttonNumber = 0;
        break;
    case WebMouseEvent::ButtonMiddle:
        buttonNumber = 1;
        break;
    case WebMouseEvent::ButtonRight:
        buttonNumber = 2;
        break;
    default:
        return;
    }
    bool ctrl = mouseEvent->modifiers & WebMouseEvent::ControlKey;
    bool shift = mouseEvent->modifiers & WebMouseEvent::ShiftKey;
    bool alt = mouseEvent->modifiers & WebMouseEvent::AltKey;
    bool meta = mouseEvent->modifiers & WebMouseEvent::MetaKey;

    NavigationPolicy userPolicy = *policy;
    navigationPolicyFromMouseEvent(buttonNumber, ctrl, shift, alt, meta, &userPolicy);
    // User and app agree that we want a new window; let the app override the decorations.
    if (userPolicy == NavigationPolicyNewWindow && *policy == NavigationPolicyNewPopup)
        return;
    *policy = userPolicy;
}

WebNavigationPolicy ChromeClientImpl::getNavigationPolicy()
{
    // If our default configuration was modified by a script or wasn't
    // created by a user gesture, then show as a popup. Else, let this
    // new window be opened as a toplevel window.
    bool asPopup = !m_toolbarsVisible
        || !m_statusbarVisible
        || !m_scrollbarsVisible
        || !m_menubarVisible
        || !m_resizable;

    NavigationPolicy policy = NavigationPolicyNewForegroundTab;
    if (asPopup)
        policy = NavigationPolicyNewPopup;
    updatePolicyForEvent(WebViewImpl::currentInputEvent(), &policy);

    return static_cast<WebNavigationPolicy>(policy);
}

void ChromeClientImpl::show(NavigationPolicy navigationPolicy)
{
    if (!m_webView->client())
        return;

    WebNavigationPolicy policy = static_cast<WebNavigationPolicy>(navigationPolicy);
    if (policy == WebNavigationPolicyIgnore)
        policy = getNavigationPolicy();
    m_webView->client()->show(policy);
}

bool ChromeClientImpl::canRunModal()
{
    return !!m_webView->client();
}

void ChromeClientImpl::runModal()
{
    if (m_webView->client())
        m_webView->client()->runModal();
}

void ChromeClientImpl::setToolbarsVisible(bool value)
{
    m_toolbarsVisible = value;
}

bool ChromeClientImpl::toolbarsVisible()
{
    return m_toolbarsVisible;
}

void ChromeClientImpl::setStatusbarVisible(bool value)
{
    m_statusbarVisible = value;
}

bool ChromeClientImpl::statusbarVisible()
{
    return m_statusbarVisible;
}

void ChromeClientImpl::setScrollbarsVisible(bool value)
{
    m_scrollbarsVisible = value;
    WebFrameImpl* webFrame = static_cast<WebFrameImpl*>(m_webView->mainFrame());
    if (webFrame)
        webFrame->setCanHaveScrollbars(value);
}

bool ChromeClientImpl::scrollbarsVisible()
{
    return m_scrollbarsVisible;
}

void ChromeClientImpl::setMenubarVisible(bool value)
{
    m_menubarVisible = value;
}

bool ChromeClientImpl::menubarVisible()
{
    return m_menubarVisible;
}

void ChromeClientImpl::setResizable(bool value)
{
    m_resizable = value;
}

void ChromeClientImpl::addMessageToConsole(MessageSource source,
                                           MessageLevel level,
                                           const String& message,
                                           unsigned lineNumber,
                                           const String& sourceID)
{
    if (m_webView->client()) {
        m_webView->client()->didAddMessageToConsole(
            WebConsoleMessage(static_cast<WebConsoleMessage::Level>(level), message),
            sourceID,
            lineNumber);
    }
}

bool ChromeClientImpl::canRunBeforeUnloadConfirmPanel()
{
    return !!m_webView->client();
}

bool ChromeClientImpl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
{
    if (m_webView->client()) {
        return m_webView->client()->runModalBeforeUnloadDialog(
            WebFrameImpl::fromFrame(frame), message);
    }
    return false;
}

void ChromeClientImpl::closeWindowSoon()
{
    // Make sure this Page can no longer be found by JS.
    m_webView->page()->clearPageGroup();

    // Make sure that all loading is stopped.  Ensures that JS stops executing!
    m_webView->mainFrame()->stopLoading();

    if (m_webView->client())
        m_webView->client()->closeWidgetSoon();
}

// Although a Frame is passed in, we don't actually use it, since we
// already know our own m_webView.
void ChromeClientImpl::runJavaScriptAlert(Frame* frame, const String& message)
{
    if (m_webView->client()) {
        if (WebUserGestureIndicator::isProcessingUserGesture())
            WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
        m_webView->client()->runModalAlertDialog(
            WebFrameImpl::fromFrame(frame), message);
    }
}

// See comments for runJavaScriptAlert().
bool ChromeClientImpl::runJavaScriptConfirm(Frame* frame, const String& message)
{
    if (m_webView->client()) {
        if (WebUserGestureIndicator::isProcessingUserGesture())
            WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
        return m_webView->client()->runModalConfirmDialog(
            WebFrameImpl::fromFrame(frame), message);
    }
    return false;
}

// See comments for runJavaScriptAlert().
bool ChromeClientImpl::runJavaScriptPrompt(Frame* frame,
                                           const String& message,
                                           const String& defaultValue,
                                           String& result)
{
    if (m_webView->client()) {
        if (WebUserGestureIndicator::isProcessingUserGesture())
            WebUserGestureIndicator::currentUserGestureToken().setJavascriptPrompt();
        WebString actualValue;
        bool ok = m_webView->client()->runModalPromptDialog(
            WebFrameImpl::fromFrame(frame),
            message,
            defaultValue,
            &actualValue);
        if (ok)
            result = actualValue;
        return ok;
    }
    return false;
}

void ChromeClientImpl::setStatusbarText(const String& message)
{
    if (m_webView->client())
        m_webView->client()->setStatusText(message);
}

bool ChromeClientImpl::tabsToLinks()
{
    return m_webView->tabsToLinks();
}

IntRect ChromeClientImpl::windowResizerRect() const
{
    IntRect result;
    if (m_webView->client())
        result = m_webView->client()->windowResizerRect();
    return result;
}

void ChromeClientImpl::invalidateContentsAndRootView(const IntRect& updateRect)
{
    if (updateRect.isEmpty())
        return;
    m_webView->invalidateRect(updateRect);
}

void ChromeClientImpl::invalidateContentsForSlowScroll(const IntRect& updateRect)
{
    invalidateContentsAndRootView(updateRect);
}

void ChromeClientImpl::scheduleAnimation()
{
    m_webView->scheduleAnimation();
}

void ChromeClientImpl::scroll(
    const IntSize& scrollDelta, const IntRect& scrollRect,
    const IntRect& clipRect)
{
    if (!m_webView->isAcceleratedCompositingActive()) {
        if (m_webView->client()) {
            int dx = scrollDelta.width();
            int dy = scrollDelta.height();
            m_webView->client()->didScrollRect(dx, dy, intersection(scrollRect, clipRect));
        }
    } else
        m_webView->scrollRootLayerRect(scrollDelta, clipRect);
}

IntPoint ChromeClientImpl::screenToRootView(const IntPoint& point) const
{
    IntPoint windowPoint(point);

    if (m_webView->client()) {
        WebRect windowRect = m_webView->client()->windowRect();
        windowPoint.move(-windowRect.x, -windowRect.y);
    }

    return windowPoint;
}

IntRect ChromeClientImpl::rootViewToScreen(const IntRect& rect) const
{
    IntRect screenRect(rect);

    if (m_webView->client()) {
        WebRect windowRect = m_webView->client()->windowRect();
        screenRect.move(windowRect.x, windowRect.y);
    }

    return screenRect;
}

WebScreenInfo ChromeClientImpl::screenInfo() const
{
    return m_webView->client() ? m_webView->client()->screenInfo() : WebScreenInfo();
}

void ChromeClientImpl::contentsSizeChanged(Frame* frame, const IntSize& size) const
{
    m_webView->didChangeContentsSize();

    WebFrameImpl* webframe = WebFrameImpl::fromFrame(frame);
    webframe->didChangeContentsSize(size);
    if (webframe->client())
        webframe->client()->didChangeContentsSize(webframe, size);
}

void ChromeClientImpl::deviceOrPageScaleFactorChanged() const
{
    m_webView->deviceOrPageScaleFactorChanged();
}

void ChromeClientImpl::didProgrammaticallyScroll(Frame* frame, const IntPoint& scrollPoint) const
{
    ASSERT(frame->view()->inProgrammaticScroll());
    if (frame->page()->mainFrame() == frame)
        m_webView->didProgrammaticallyScroll(scrollPoint);
}

void ChromeClientImpl::layoutUpdated(Frame* frame) const
{
    m_webView->layoutUpdated(WebFrameImpl::fromFrame(frame));
}

void ChromeClientImpl::mouseDidMoveOverElement(
    const HitTestResult& result, unsigned modifierFlags)
{
    if (!m_webView->client())
        return;

    WebURL url;
    // Find out if the mouse is over a link, and if so, let our UI know...
    if (result.isLiveLink() && !result.absoluteLinkURL().string().isEmpty())
        url = result.absoluteLinkURL();
    else if (result.innerNonSharedNode()
             && (result.innerNonSharedNode()->hasTagName(HTMLNames::objectTag)
                 || result.innerNonSharedNode()->hasTagName(HTMLNames::embedTag))) {
        RenderObject* object = result.innerNonSharedNode()->renderer();
        if (object && object->isWidget()) {
            Widget* widget = toRenderWidget(object)->widget();
            if (widget && widget->isPluginContainer()) {
                WebPluginContainerImpl* plugin = static_cast<WebPluginContainerImpl*>(widget);
                url = plugin->plugin()->linkAtPosition(result.roundedPointInInnerNodeFrame());
            }
        }
    }

    m_webView->client()->setMouseOverURL(url);
}

void ChromeClientImpl::setToolTip(const String& tooltipText, TextDirection dir)
{
    if (!m_webView->client())
        return;
    WebTextDirection textDirection = (dir == RTL) ?
        WebTextDirectionRightToLeft :
        WebTextDirectionLeftToRight;
    m_webView->client()->setToolTipText(
        tooltipText, textDirection);
}

void ChromeClientImpl::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const
{
    m_webView->updatePageDefinedPageScaleConstraints(arguments);
}

void ChromeClientImpl::print(Frame* frame)
{
    if (m_webView->client())
        m_webView->client()->printPage(WebFrameImpl::fromFrame(frame));
}

PassOwnPtr<ColorChooser> ChromeClientImpl::createColorChooser(ColorChooserClient* chooserClient, const Color&)
{
    OwnPtr<ColorChooserUIController> controller;
    if (RuntimeEnabledFeatures::pagePopupEnabled())
        controller = adoptPtr(new ColorChooserPopupUIController(this, chooserClient));
    else
        controller = adoptPtr(new ColorChooserUIController(this, chooserClient));
    controller->openUI();
    return controller.release();
}
PassOwnPtr<WebColorChooser> ChromeClientImpl::createWebColorChooser(WebColorChooserClient* chooserClient, const WebColor& initialColor)
{
    WebViewClient* client = m_webView->client();
    if (!client)
        return nullptr;
    return adoptPtr(client->createColorChooser(chooserClient, initialColor));
}

PassRefPtr<DateTimeChooser> ChromeClientImpl::openDateTimeChooser(DateTimeChooserClient* pickerClient, const DateTimeChooserParameters& parameters)
{
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
    return DateTimeChooserImpl::create(this, pickerClient, parameters);
#else
    return ExternalDateTimeChooser::create(this, m_webView->client(), pickerClient, parameters);
#endif
}

void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
{
    WebViewClient* client = m_webView->client();
    if (!client)
        return;

    WebFileChooserParams params;
    params.multiSelect = fileChooser->settings().allowsMultipleFiles;
    params.directory = fileChooser->settings().allowsDirectoryUpload;
    params.acceptTypes = fileChooser->settings().acceptTypes();
    params.selectedFiles = fileChooser->settings().selectedFiles;
    if (params.selectedFiles.size() > 0)
        params.initialValue = params.selectedFiles[0];
#if ENABLE(MEDIA_CAPTURE)
    params.useMediaCapture = fileChooser->settings().useMediaCapture;
#endif
    WebFileChooserCompletionImpl* chooserCompletion =
        new WebFileChooserCompletionImpl(fileChooser);

    if (client->runFileChooser(params, chooserCompletion))
        return;

    // Choosing failed, so do callback with an empty list.
    chooserCompletion->didChooseFile(WebVector<WebString>());
}

void ChromeClientImpl::enumerateChosenDirectory(FileChooser* fileChooser)
{
    WebViewClient* client = m_webView->client();
    if (!client)
        return;

    WebFileChooserCompletionImpl* chooserCompletion =
        new WebFileChooserCompletionImpl(fileChooser);

    ASSERT(fileChooser && fileChooser->settings().selectedFiles.size());

    // If the enumeration can't happen, call the callback with an empty list.
    if (!client->enumerateChosenDirectory(fileChooser->settings().selectedFiles[0], chooserCompletion))
        chooserCompletion->didChooseFile(WebVector<WebString>());
}

void ChromeClientImpl::popupOpened(PopupContainer* popupContainer,
                                   const IntRect& bounds,
                                   bool handleExternally)
{
    // For Autofill popups, if the popup will not be fully visible, we shouldn't
    // show it at all. Among other things, this prevents users from being able
    // to interact via the keyboard with an invisible popup.
    if (popupContainer->popupType() == PopupContainer::Suggestion) {
        FrameView* view = m_webView->page()->mainFrame()->view();
        IntRect visibleRect = view->visibleContentRect(ScrollableArea::IncludeScrollbars);
        // |bounds| is in screen coordinates, so make sure to convert it to
        // content coordinates prior to comparing to |visibleRect|.
        IntRect screenRect = bounds;
        screenRect.setLocation(view->screenToContents(bounds.location()));
        if (!visibleRect.contains(screenRect)) {
            m_webView->hideAutofillPopup();
            return;
        }
    }

    if (!m_webView->client())
        return;

    WebWidget* webwidget;
    if (handleExternally) {
        WebPopupMenuInfo popupInfo;
        getPopupMenuInfo(popupContainer, &popupInfo);
        webwidget = m_webView->client()->createPopupMenu(popupInfo);
    } else {
        webwidget = m_webView->client()->createPopupMenu(
            convertPopupType(popupContainer->popupType()));
        // We only notify when the WebView has to handle the popup, as when
        // the popup is handled externally, the fact that a popup is showing is
        // transparent to the WebView.
        m_webView->popupOpened(popupContainer);
    }
    static_cast<WebPopupMenuImpl*>(webwidget)->initialize(popupContainer, bounds);
}

void ChromeClientImpl::popupClosed(WebCore::PopupContainer* popupContainer)
{
    m_webView->popupClosed(popupContainer);
}

void ChromeClientImpl::setCursor(const WebCore::Cursor& cursor)
{
    setCursor(WebCursorInfo(cursor));
}

void ChromeClientImpl::setCursor(const WebCursorInfo& cursor)
{
#if OS(DARWIN)
    // On Mac the mousemove event propagates to both the popup and main window.
    // If a popup is open we don't want the main window to change the cursor.
    if (m_webView->hasOpenedPopup())
        return;
#endif
    if (m_webView->client())
        m_webView->client()->didChangeCursor(cursor);
}

void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor)
{
    setCursor(cursor);
}

void ChromeClientImpl::formStateDidChange(const Node* node)
{
    if (m_webView->client())
        m_webView->client()->didChangeFormState(WebNode(const_cast<Node*>(node)));

    // The current history item is not updated yet.  That happens lazily when
    // WebFrame::currentHistoryItem is requested.
    WebFrameImpl* webframe = WebFrameImpl::fromFrame(node->document()->frame());
    if (webframe->client())
        webframe->client()->didUpdateCurrentHistoryItem(webframe);
}

void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer,
                                        WebPopupMenuInfo* info)
{
    const Vector<PopupItem*>& inputItems = popupContainer->popupData();

    WebVector<WebMenuItemInfo> outputItems(inputItems.size());

    for (size_t i = 0; i < inputItems.size(); ++i) {
        const PopupItem& inputItem = *inputItems[i];
        WebMenuItemInfo& outputItem = outputItems[i];

        outputItem.label = inputItem.label;
        outputItem.enabled = inputItem.enabled;
        if (inputItem.textDirection == WebCore::RTL)
            outputItem.textDirection = WebTextDirectionRightToLeft;
        else
            outputItem.textDirection = WebTextDirectionLeftToRight;
        outputItem.hasTextDirectionOverride = inputItem.hasTextDirectionOverride;

        switch (inputItem.type) {
        case PopupItem::TypeOption:
            outputItem.type = WebMenuItemInfo::Option;
            break;
        case PopupItem::TypeGroup:
            outputItem.type = WebMenuItemInfo::Group;
            break;
        case PopupItem::TypeSeparator:
            outputItem.type = WebMenuItemInfo::Separator;
            break;
        default:
            ASSERT_NOT_REACHED();
        }
    }

    info->itemHeight = popupContainer->menuItemHeight();
    info->itemFontSize = popupContainer->menuItemFontSize();
    info->selectedIndex = popupContainer->selectedIndex();
    info->items.swap(outputItems);
    info->rightAligned = popupContainer->menuStyle().textDirection() == RTL;
}

void ChromeClientImpl::postAccessibilityNotification(AccessibilityObject* obj, AXObjectCache::AXNotification notification)
{
    // Alert assistive technology about the accessibility object notification.
    if (obj)
        m_webView->client()->postAccessibilityNotification(WebAccessibilityObject(obj), toWebAccessibilityNotification(notification));
}

String ChromeClientImpl::acceptLanguages()
{
    return m_webView->client()->acceptLanguages();
}

bool ChromeClientImpl::paintCustomOverhangArea(GraphicsContext* context, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect)
{
    Frame* frame = m_webView->mainFrameImpl()->frame();
    WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(frame);
    if (pluginContainer)
        return pluginContainer->paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
    return false;
}

GraphicsLayerFactory* ChromeClientImpl::graphicsLayerFactory() const
{
    return m_webView->graphicsLayerFactory();
}

void ChromeClientImpl::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
{
    m_webView->setRootGraphicsLayer(graphicsLayer);
}

void ChromeClientImpl::scheduleCompositingLayerFlush()
{
    m_webView->scheduleCompositingLayerSync();
}

ChromeClient::CompositingTriggerFlags ChromeClientImpl::allowedCompositingTriggers() const
{
    if (!m_webView->allowsAcceleratedCompositing())
        return 0;

    CompositingTriggerFlags flags = 0;
    Settings* settings = m_webView->page()->settings();
    if (settings->acceleratedCompositingFor3DTransformsEnabled())
        flags |= ThreeDTransformTrigger;
    if (settings->acceleratedCompositingForVideoEnabled())
        flags |= VideoTrigger;
    if (settings->acceleratedCompositingForPluginsEnabled())
        flags |= PluginTrigger;
    if (settings->acceleratedCompositingForAnimationEnabled())
        flags |= AnimationTrigger;
    if (settings->acceleratedCompositingForCanvasEnabled())
        flags |= CanvasTrigger;
    if (settings->acceleratedCompositingForScrollableFramesEnabled())
        flags |= ScrollableInnerFrameTrigger;
    if (settings->acceleratedCompositingForFiltersEnabled())
        flags |= FilterTrigger;

    return flags;
}

void ChromeClientImpl::enterFullScreenForElement(Element* element)
{
    m_webView->enterFullScreenForElement(element);
}

void ChromeClientImpl::exitFullScreenForElement(Element* element)
{
    m_webView->exitFullScreenForElement(element);
}

bool ChromeClientImpl::hasOpenedPopup() const
{
    return m_webView->hasOpenedPopup();
}

PassRefPtr<PopupMenu> ChromeClientImpl::createPopupMenu(Frame& frame, PopupMenuClient* client) const
{
    if (WebViewImpl::useExternalPopupMenus())
        return adoptRef(new ExternalPopupMenu(frame, client, m_webView->client()));

    return adoptRef(new PopupMenuChromium(frame, client));
}

PagePopup* ChromeClientImpl::openPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView)
{
    ASSERT(m_pagePopupDriver);
    return m_pagePopupDriver->openPagePopup(client, originBoundsInRootView);
}

void ChromeClientImpl::closePagePopup(PagePopup* popup)
{
    ASSERT(m_pagePopupDriver);
    m_pagePopupDriver->closePagePopup(popup);
}

void ChromeClientImpl::setPagePopupDriver(PagePopupDriver* driver)
{
    ASSERT(driver);
    m_pagePopupDriver = driver;
}

void ChromeClientImpl::resetPagePopupDriver()
{
    m_pagePopupDriver = m_webView;
}

bool ChromeClientImpl::isPasswordGenerationEnabled() const
{
    return m_webView->passwordGeneratorClient();
}

void ChromeClientImpl::openPasswordGenerator(HTMLInputElement* input)
{
    ASSERT(isPasswordGenerationEnabled());
    WebInputElement webInput(input);
    m_webView->passwordGeneratorClient()->openPasswordGenerator(webInput);
}

bool ChromeClientImpl::shouldRunModalDialogDuringPageDismissal(const DialogType& dialogType, const String& dialogMessage, FrameLoader::PageDismissalType dismissalType) const
{
    const char* kDialogs[] = {"alert", "confirm", "prompt", "showModalDialog"};
    int dialog = static_cast<int>(dialogType);
    ASSERT_WITH_SECURITY_IMPLICATION(0 <= dialog && dialog < static_cast<int>(arraysize(kDialogs)));

    const char* kDismissals[] = {"beforeunload", "pagehide", "unload"};
    int dismissal = static_cast<int>(dismissalType) - 1; // Exclude NoDismissal.
    ASSERT_WITH_SECURITY_IMPLICATION(0 <= dismissal && dismissal < static_cast<int>(arraysize(kDismissals)));

    WebKit::Platform::current()->histogramEnumeration("Renderer.ModalDialogsDuringPageDismissal", dismissal * arraysize(kDialogs) + dialog, arraysize(kDialogs) * arraysize(kDismissals));

    String message = String("Blocked ") + kDialogs[dialog] + "('" + dialogMessage + "') during " + kDismissals[dismissal] + ".";
    m_webView->mainFrame()->addMessageToConsole(WebConsoleMessage(WebConsoleMessage::LevelError, message));

    return false;
}

bool ChromeClientImpl::shouldRubberBandInDirection(WebCore::ScrollDirection direction) const
{
    ASSERT(direction != WebCore::ScrollUp && direction != WebCore::ScrollDown);

    if (!m_webView->client())
        return false;

    if (direction == WebCore::ScrollLeft)
        return !m_webView->client()->historyBackListCount();
    if (direction == WebCore::ScrollRight)
        return !m_webView->client()->historyForwardListCount();

    ASSERT_NOT_REACHED();
    return true;
}

void ChromeClientImpl::numWheelEventHandlersChanged(unsigned numberOfWheelHandlers)
{
    m_webView->numberOfWheelEventHandlersChanged(numberOfWheelHandlers);
}

void ChromeClientImpl::needTouchEvents(bool needsTouchEvents)
{
    m_webView->hasTouchEventHandlers(needsTouchEvents);
}

bool ChromeClientImpl::requestPointerLock()
{
    return m_webView->requestPointerLock();
}

void ChromeClientImpl::requestPointerUnlock()
{
    return m_webView->requestPointerUnlock();
}

bool ChromeClientImpl::isPointerLocked()
{
    return m_webView->isPointerLocked();
}

void ChromeClientImpl::annotatedRegionsChanged()
{
    WebViewClient* client = m_webView->client();
    if (client)
        client->draggableRegionsChanged();
}

void ChromeClientImpl::didAssociateFormControls(const Vector<RefPtr<Element> >& elements)
{
    if (!m_webView->autofillClient())
        return;
    WebVector<WebNode> elementVector(static_cast<size_t>(elements.size()));
    size_t elementsCount = elements.size();
    for (size_t i = 0; i < elementsCount; ++i)
        elementVector[i] = elements[i];
    m_webView->autofillClient()->didAssociateFormControls(elementVector);
}

#if ENABLE(NAVIGATOR_CONTENT_UTILS)
PassOwnPtr<NavigatorContentUtilsClientImpl> NavigatorContentUtilsClientImpl::create(WebViewImpl* webView)
{
    return adoptPtr(new NavigatorContentUtilsClientImpl(webView));
}

NavigatorContentUtilsClientImpl::NavigatorContentUtilsClientImpl(WebViewImpl* webView)
    : m_webView(webView)
{
}

void NavigatorContentUtilsClientImpl::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title)
{
    m_webView->client()->registerProtocolHandler(scheme, baseURL, url, title);
}
#endif

} // namespace WebKit


text:
package comirva.audio.util.math;

/**
 * Normalized Convolution
 *
 *
Description:

 * This class implements a fast version of the convolution of a filter,
 * represented as a vector, with another vector obtained from a given matrix.
 * For extracting the vector out of the matrix one can specifiy, if column or
 * row vectors should be used. This is done for all vectors in the matrix.

 *

 * For example if you like to blur a matrix using a gaussian filter, you hand in
 * the filter and specify, which dimension of the matrix to blur.

 *

 * Normalized means, that the filter vector used in the constructor will get
 * normalized, such that the sum of the filter weights is 1. Furthermore for the
 * first and the last elements, where one cannot apply the complete filter, a
 * truncated and normalized filter will be used.

 *

 * The general purpose is to perfrom the convolution in a fast way and to reuse
 * the convolution object for a large number of convolutions of the same type.
 *
 * @author Klaus Seyerlehner
 * @version 1.0
 */
public class NormalizedConvolution
{
  //fields
  protected double[] filter;

  //implementation details
  private double[][] normalizedFilterArray;

  /**
   * Creates a NormalizedConvolution object, which can be used to
   * compute the convolution a matrix with the given filter by using the
   * convolute() methode.
   *
   * @param filter double[] the filter used for the convolution e.g. a gaussian
   *                        filter
   *
   * @throws IllegalArgumentException the given filter must not be a null value
   *                                  and must have an odd length greater or
   *                                  equal to 3
   */
  public NormalizedConvolution(double[] filter) throws IllegalArgumentException
  {
    //check arguments
    if(filter == null)
      throw new IllegalArgumentException("the given filter must not be a null value;");

    if(filter.length % 2 != 1 || filter.length < 3)
      throw new IllegalArgumentException("the given filter must have an odd length greater or equal to 3;");

    //set fields
    this.filter = filter;

     //compute normalized filter array
    this.normalizedFilterArray = getNormalizedFilterArray(filter);
  }

  /**
   * Perform the convolution of the given matrix according to the specified
   * dimension. The filter has been fixed during the construction of the
   * NormalizedConvolution object.
   *
   * @param A Matrix the matrix to convolute with
   * @param firstDimension boolean if true each of the row vectors will get
   *                               convoluted with the filter, otherwise each
   *                               of the column vectors will be used to
   *                               convolute with
   * @return Matrix as result the completely convoluted matrix will be returned
   */
  public Matrix convolute(Matrix A, boolean firstDimension)
  {
    double[][] data;
    Matrix B;

    //depending on the dimension either convolute the row or column vectors
    if(firstDimension)
    {
      data = A.getArrayCopy();

      //for each row vector compute the convolution with the filter
      for (int i = 0; i < data.length; i++)
        data[i] = computeConvolution(data[i], normalizedFilterArray);

      B = new Matrix(data);
    }
    else
    {
      B = A.transpose();
      data = B.getArray();

      //for each column vector compute the convolution with the filter
      for (int i = 0; i < data.length; i++)
        data[i] = computeConvolution(data[i], normalizedFilterArray);

      B = new Matrix(data);
      B = B.transpose();
    }
    return B;
  }

  /**
   * Computes the convolution of a vector and a filter.
   *
   * @param data double[] the input vector to convolute with the filter
   * @param filterArray double[][] a filter array containing the normalized
   *                               filter and truncated normalized filters for
   *                               the start and ending elements of the vector.
   * @return double[] the result of the convolution
   */
  private double[] computeConvolution(double[] data, double[][] filterArray)
  {
    double[] output = new double[data.length];
    double sum = 0;
    int halfFilter = filterArray.length/2;

    //compute for each position the convolution with the filter
    for(int i = 0; i < data.length; i++)
    {
      sum = 0;
      if(i < halfFilter)
      {
        //for the first elements use some truncated filters
        for(int j = 0; j < filterArray[i].length; j++)
          sum += filterArray[i][j] * data[j];
      }
      else if(i >= (data.length - halfFilter))
      {
        //for the last elements use some truncated filters
        int filterArrayIndex = filterArray.length - (data.length - i);
        for(int j = 0; j < filterArray[filterArrayIndex].length; j++)
          sum += filterArray[filterArrayIndex][j] * data[i + j - halfFilter];
      }
      else
      {
        //for all other elements use the complete filter
        int filterArrayIndex = halfFilter;
        for(int j = 0; j < filterArray[filterArrayIndex].length; j++)
          sum += filterArray[filterArrayIndex][j] * data[i + j - halfFilter];
      }

      output[i] = sum;
    }

    return output;
  }

  /**
   * Computes normalized and truncated filters and returns them in an array.
   *
   * @param filter double[] filter to compute normalized and truncated versions of
   * @return double[][] an array containing normalized and truncated version of
   *                    the given filter
   */
  private double[][] getNormalizedFilterArray(double[] filter)
  {
    double[][] array = new double[filter.length][];

    int filterCount = 0;

    //computes all possible truncated versions of the filter
    for(int start = filter.length / 2; start > - filter.length / 2 - 1; start--)
    {
      array[filterCount] = new double[filter.length - Math.abs(start)];
      for (int i = 0, indexCount = 0; i + start < filter.length && i < filter.length; i++)
      {
        if(start + i >= 0)
        {
          array[filterCount][indexCount] = filter[start + i];
          indexCount++;
        }
      }

      //normalize filter
      normalizeFilter(array[filterCount]);
      filterCount++;
    }

    return array;
  }

  /**
   * Normalizes a given filter array in place.
   *
   * @param filter double[] the filter to normalize
   */
  private void normalizeFilter(double[] filter)
  {
    double sum = 0;

    //compute filter sum
    for(int i = 0; i < filter.length; i++)
      sum += filter[i];

    //normalize
    for(int i = 0; i < filter.length; i++)
      filter[i]/=sum;
  }
}


text:
* Description: AM3352 (TI) based single board computer
* Type: Single Board Computer
* Tool: KiCad
* Author: Olimex
* License: Creative Commons Attribution-Share Alike 3.0 United States License
* [Schematic](https://github.com/OLIMEX/OLINUXINO/tree/master/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_B)
* [Layout](https://github.com/OLIMEX/OLINUXINO/tree/master/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_B)


text:
<法規>
<法規性質>命令</法規性質>
<英文法規名稱>Enforcement Rules of Genetic Health Act</英文法規名稱>
<中文法規名稱>優生保健法施行細則</中文法規名稱>
<法規網址>https://law.moj.gov.tw/Eng/LawClass/LawAll.aspx?pcode=L0070002</法規網址>
<最新英文異動日期>20120405</最新英文異動日期>
<廢止註記>
</廢止註記>
<附件>
  <檔案>
    <檔案名稱><![CDATA[Annex I Items of health or pre-marital examination.PDF]]></檔案名稱>
    <下載網址>https://law.moj.gov.tw/Eng/LawClass/LawGetFile.ashx?FileId=0000004543</下載網址>
  </檔案>
  <檔案>
    <檔案名稱><![CDATA[Annex I Items of health or pre-marital examination.doc]]></檔案名稱>
    <下載網址>https://law.moj.gov.tw/Eng/LawClass/LawGetFile.ashx?FileId=0000001568</下載網址>
  </檔案>
  <檔案>
    <檔案名稱><![CDATA[Annex II Scope of medical grounds for the identification of pregnancy or childbirth which might lead to life-threatening or endanger physical or mental health.PDF]]></檔案名稱>
    <下載網址>https://law.moj.gov.tw/Eng/LawClass/LawGetFile.ashx?FileId=0000004544</下載網址>
  </檔案>
  <檔案>
    <檔案名稱><![CDATA[Annex II Scope of medical grounds for the identification of pregnancy or childbirth which might lead to life-threatening or endanger physical or mental health.doc]]></檔案名稱>
    <下載網址>https://law.moj.gov.tw/Eng/LawClass/LawGetFile.ashx?FileId=0000001569</下載網址>
  </檔案>
  <檔案>
    <檔案名稱><![CDATA[Annex III The scope of the relevant medical reasons in identifying potential abnormal development on fetus.PDF]]></檔案名稱>
    <下載網址>https://law.moj.gov.tw/Eng/LawClass/LawGetFile.ashx?FileId=0000004545</下載網址>
  </檔案>
  <檔案>
    <檔案名稱><![CDATA[Annex III The scope of the relevant medical reasons in identifying potential abnormal development on fetus.doc]]></檔案名稱>
    <下載網址>https://law.moj.gov.tw/Eng/LawClass/LawGetFile.ashx?FileId=0000001570</下載網址>
  </檔案>
</附件>
<沿革內容><![CDATA[1.Promulgated on January 04, 1985
2.Amended on May 09, 2000
3.Amended on April 05, 2012]]></沿革內容>
<前言><![CDATA[]]></前言>
<法規內容>
  <條文>
    <條號>Article 1</條號>
    <條文內容><![CDATA[The rules are prescribed pursuant to Article 17 in the Genetic Health Act (hereinafter referred to as the Act).]]></條文內容>
  </條文>
  <條文>
    <條號>Article 2</條號>
    <條文內容><![CDATA[Items of the health or pre-marital examination referred to in Article 6 see Annex I]]></條文內容>
  </條文>
  <條文>
    <條號>Article 3</條號>
    <條文內容><![CDATA[The Necessity stated in section 1 of Article 6 means the following circumstances:
1. Persons suspected to have a genetic, infectious or psychiatric diseases with genetic effects.
2. Persons whose relative by blood within the fourth degree of kin is suspected suffering from hereditary genetic diseases .
3. Persons are suspected of having a disease that requires a health examination.
When encountering one of above cases, public health care institutions, private hospitals and clinics at all levels shall report to local competent authority.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 4</條號>
    <條文內容><![CDATA[The fertility regulation service and guidance stated in section 1 of Article 7 refer to the provision of various contraceptive methods, equipment, medicines, ligation, and infertility diagnosis for men and women with reproductive capacity; however, the implementation of ligation shall follow the terms set in Article 10.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 5</條號>
    <條文內容><![CDATA[The health care services and guidance for pre-pregnancy, prenatal, perinatal, post pregnancy stated in section 2 of Article 7 means providing examinations, delivery, nutrition and health guidance during pregnancy.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 6</條號>
    <條文內容><![CDATA[The infant and toddler health services referred to section 3 of Article 7 of the Act mean the provision of health examinations, vaccinations, required diagnosis and treatments, nutrition and health guidance for infants under one year old and children over one year old before school-starting age.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 7</條號>
    <條文內容><![CDATA[The examinations, services, guidance and education referred to Article 6 and 7 shall be carried out by public health care institutions, private hospitals and clinics at all levels.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 8</條號>
    <條文內容><![CDATA[Public health care institutions, private hospitals and clinics at all levels shall carry out outpatient activities and make case records, and persuade persons who need to carry out health or pre-marital check to get such examination, as well as persuade patient to receive treatment and fertility regulation guidance. Public health care institutions, private hospitals and clinics at all levels, if necessary, shall conduct family visits and educational advocacy.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 9</條號>
    <條文內容><![CDATA[(Delete)]]></條文內容>
  </條文>
  <條文>
    <條號>Article 10</條號>
    <條文內容><![CDATA[The scope for persons suspected to have genetic defects , infectious diseases or mental illness referred to in this Act is as follows:
1. Persons who will affect normal fetal development, such as pregnant women suffering from phenylketonuria or Rubella.
2. Persons who are suffering from severe mental retardation or schizophrenia and therefore incapable to take care of baby.
3. Persons who may transmit abnormal chromosomes or genes to future generations, such as patients suffering from Down syndrome or Huntington's disease.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 11</條號>
    <條文內容><![CDATA[The scope of medical grounds of pregnancy or delivery may cause life threatening risk or detrimental to her physical or mental health referred to in this Act is described in Annex II.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 12</條號>
    <條文內容><![CDATA[The scope of medical grounds regarding the risk of teratogenesis present for the fetus by medcial consideration referred to item 2 of section 1 of Article 9
in this Act is illustrated in Annex III.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 13</條號>
    <條文內容><![CDATA[The scope of marriages prohibited by law referred to item 5, section 1 of Article 9 in this Act is prescribed pursuant to provisions of Article 983 of the Civil Code.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 13-1</條號>
    <條文內容><![CDATA[Mental health or family life is likely to be affected due to pregnancy or childbirth referred to item 6, section 1 of Article 9, shall not be identified based on the reason of fetal gender differences.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 14</條號>
    <條文內容><![CDATA[Cases set out in Article 10 to Article 13 shall be determined by the designated physician performing induced abortion or ligation in accordance with provisions.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 15</條號>
    <條文內容><![CDATA[Except required medical treatments, induced abortion shall be practiced within twenty four weeks of pregnancy. induced abortion within 12 weeks pregnancy shall be implemented by induced abortion specialists in hospitals or clinics; for pregnancy more than 12 weeks; such abortion shall be implemented by induced abortion specialist in hospitals under the condition of hospitalization.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 16</條號>
    <條文內容><![CDATA[The agency imposing fines set out in this Act are the municipality and county (city) government.]]></條文內容>
  </條文>
  <條文>
    <條號>Article 17</條號>
    <條文內容><![CDATA[This set of Regulations is implemented on the day of announcement.]]></條文內容>
  </條文>
</法規內容>
</法規>


text:
#ifndef STRINGBUF_H
#define STRINGBUF_H

/**
 * \defgroup cbff SBUF Formatting Flags
 * @{
 */

/**
 * \def SBUF_LSPACE
 *
 * Add a leading space before the string.
 */
#define SBUF_LSPACE (1 << 0)

/**
 * \def SBUF_TSPACE
 *
 * Add a trailing space after the string.
 */
#define SBUF_TSPACE (1 << 1)

/**
 * \def SBUF_EQUALS
 *
 * Add an '=' after the string.
 */
#define SBUF_EQUALS (1 << 2)

/**
 * \def SBUF_QUOTE
 *
 * Add a single-quote before and after the string.
 */
#define SBUF_QUOTE (1 << 3)

/**
 * \def SBUF_COMMA
 *
 * Add a comma after the string.
 */
#define SBUF_COMMA (1 << 4)

/**
 * \def SBUF_LPAREN
 *
 * Add a left-parenthesis before the string.
 */
#define SBUF_LPAREN (1 << 5)

/**
 * \def SBUF_RPAREN
 *
 * Add a right-parenthesis after the string.
 */
#define SBUF_RPAREN (1 << 6)

/**
 * \def SBUF_SCOLON
 *
 * Add a semicolon after the string.
 */
#define SBUF_SCOLON (1 << 7)
/** @} */

/**
 * Reset the buffer
 *
 * \param[in] scrub If non-zero, scrub the buffer.
 */
void sbuf_reset(int scrub);

/**
 * Get a const-qualified pointer to the buffer.
 */
const char *sbuf_get_buffer(void);

/**
 * Add a string to the buffer.
 *
 * \param[in] s     String to add
 * \param[in] flags Formatting flags
 * \param[in] pos   Position at which to add the string (0 = current)
 * \return 0 on success, 1 on failure.
 */
int sbuf_add_str(const char *s, long flags, size_t pos);

/**
 * Add an unsigned integer to the buffer.
 *
 * \param[in] num Number to add
 * \param[in] flags Formatting flags
 * \return 0 on success, 1 on failure.
 */
int sbuf_add_unum(unsigned long num, long flags);

/**
 * Add a signed integer to the buffer.
 *
 * \param[in] num   Number to add
 * \param[in] flags Formatting flags
 * \return 0 on success, 1 on failure.
 */
int sbuf_add_snum(long num, long flags);

/**
 * Add a parameter string to the string buffer.
 *
 * This will add:
 *     param='value'
 *
 * to the buffer, adding a leading space between parameters.
 *
 * \param[in] param  Parameter name
 * \param[in] value  Value to set
 * \return 0 on success, 1 on error.
 */
int sbuf_add_param_str(const char *param, const char *value);

/**
 * Add a numeric parameter to the string buffer.
 *
 * This will add:
 *     param=value
 *
 * to the buffer, adding a leading space between parameters.
 *
 * \param[in] param  Parameter name
 * \param[in] value  Numeric value
 * \return 0 on success, 1 on failure.
 */
int sbuf_add_param_num(const char *param, unsigned long value);

#endif /* STRINGBUF_H */


text:
import React,{Component} from 'react'
import {Scene} from 'react-native-router-flux';

// test list
import TestsListView from './testsListView'
// test pages
// import TestFile from './testFile'
import TestImagePicker from './testImagePicker'
import TestPopupPage from './testPopupPage'
import TestPopupSelecter from './testPopupSelecter'

let scenes = [
        {
            key: 'TestImagePicker',
            comp: TestImagePicker,
        },
        {
            key:'TestPopupPage',
            comp:TestPopupPage,
        },
        {
            key: 'TestPopupSelecter',
            comp: TestPopupSelecter,
        },
    ];

// module.exports = <Scene key="tabbar" tabs={true}>
//    // scenes here
// </Scene>;

// module.exports = <Scene key="test">
//    	<Scene key='testsListView' /*initial={true}*/ hideNavBar={true} component={TestsListView} />
// 	{
// 	    scenes.map(item =>
// 	        <Scene key={item.key} component={item.comp} />)
// 	}
// </Scene>;

module.exports =
(
    <Scene key="test">
       	<Scene key='testsListView' /*initial={true}*/ hideNavBar={true} component={TestsListView} />
    	{
    	    scenes.map(item =>
    	        <Scene key={item.key} component={item.comp} />)
    	}
    </Scene>
);

// export default class testsScenes extends Component{
//   constructor(props){
//     super(props);
//   }

//   render() {
//       return (
//         <Scene key="test">
// 		   	<Scene key='testsListView' initial={true} hideNavBar={true} component={TestsListView} />
// 			{
// 			    scenes.map(item =>
// 			        <Scene key={item.key} component={item.comp} />)
// 			}
// 		</Scene>
//       );
//   }

// }


text:
php -S localhost:4001 -t www/ &
ncat -c "./reversing/00-di-why/pw_man.py ./reversing/00-di-why/pw_db.txt" -k -l 4003

# Then just sleep until killed by systemd
sleep infinity


text:
package com.wideplay.warp.persist.jdo;

import com.google.inject.*;
import com.wideplay.warp.persist.*;
import com.wideplay.warp.persist.internal.InternalWorkManager;
import com.wideplay.warp.persist.spi.*;
import org.aopalliance.intercept.MethodInterceptor;

import javax.jdo.*;
import java.lang.annotation.Annotation;
import java.util.*;

/**
 * @author Miroslav Genov
 */
public class JdoPersistenceStrategy implements PersistenceStrategy {
    private final Properties jdoProperties;
    private final String unit;
    private final Class<? extends Annotation> annotation;

    public JdoPersistenceStrategy(JdoPersistenceStrategyBuilder builder) {
        this.jdoProperties = builder.jdoProperties;
        this.unit = builder.unit;
        this.annotation = builder.annotation;
    }

    public PersistenceModule getBindings(PersistenceConfiguration persistenceConfiguration) {
        return new JdoPersistenceModule(persistenceConfiguration);
    }

    class JdoPersistenceModule extends AbstractPersistenceModule {
        private final PersistenceConfiguration config;
        private final PersistenceManagerFactoryProvider pmfProvider;
        private final PersistenceManagerProvider pmProvider;
        private final WorkManager workManager;
        private final JdoPersistenceService pService;
        // needed for bindings created in the constructor.
        private final List<Module> scheduledBindings = new ArrayList<Module>();
        private InternalWorkManager<PersistenceManager> internalWm;

        private JdoPersistenceModule(PersistenceConfiguration configuration) {
            super(configuration, annotation);
            this.config = configuration;
            this.pmfProvider = new PersistenceManagerFactoryProvider(getPersistenceUnitKey(),
                    getExtraPersistencePropertiesKey());
            internalWm = new JdoInternalWorkManager(pmfProvider);
            this.pmProvider = new PersistenceManagerProvider(internalWm);
            this.workManager = new JdoWorkManager(internalWm);
            this.pService = new JdoPersistenceService(pmfProvider);
        }

        protected void configure() {
            for (Module m : scheduledBindings) install(m);
            // Set up JDO.
            bindWithUnitAnnotation(PersistenceManagerFactory.class).toProvider(pmfProvider).in(Singleton.class);
            bindWithUnitAnnotation(PersistenceManager.class).toProvider(pmProvider);
            bindWithUnitAnnotation(PersistenceService.class).toInstance(pService);
            bindWithUnitAnnotation(JdoPersistenceService.class).toInstance(pService);
            bindWithUnitAnnotation(WorkManager.class).toInstance(workManager);

            MethodInterceptor txInterceptor = new JdoLocalTxnInterceptor(this.internalWm, config.getUnitOfWork());
            bindTransactionInterceptor(txInterceptor);

            // Set up Dynamic Finders.
            MethodInterceptor finderInterceptor = new JdoFinderInterceptor(pmProvider);
            bindFinderInterceptor(finderInterceptor);
            bindTransactionalDynamicAccessors(finderInterceptor, txInterceptor);
        }

        private Key<String> getPersistenceUnitKey() {
            if (!inMultiModulesMode()) {
                return Key.get(String.class, JdoUnit.class);
            } else {
                final Key<String> key = Key.get(String.class, JdoUnitInstance.of(annotation));
                if (unit != null) {
                    scheduledBindings.add(new AbstractModule() {
                        protected void configure() {
                            bind(key).toInstance(unit);
                        }
                    });
                }
                return key;
            }
        }

        private Key<Properties> getExtraPersistencePropertiesKey() {
            if (!inMultiModulesMode()) {
                return Key.get(Properties.class, JdoUnit.class);
            } else {
                final Key<Properties> key = Key.get(Properties.class, JdoUnitInstance.of(JdoPersistenceStrategy.this.annotation));
                if (jdoProperties != null) {
                    scheduledBindings.add(new AbstractModule() {
                        protected void configure() {
                            bind(key).toInstance(jdoProperties);
                        }
                    });
                }
                return key;
            }
        }

        public void visit(PersistenceModuleVisitor visitor) {
            if (unitOfWorkRequest()) {
                visitor.publishWorkManager(this.workManager);
                visitor.publishPersistenceService(this.pService);
            }
        }
    }

    public static JdoPersistenceStrategyBuilder builder() {
        return new JdoPersistenceStrategyBuilder();
    }

    public static class JdoPersistenceStrategyBuilder implements PersistenceStrategyBuilder<JdoPersistenceStrategy> {
        private Properties jdoProperties;
        private String unit;
        private Class<? extends Annotation> annotation;

        public JdoPersistenceStrategyBuilder properties(Properties jpaProperties) {
            this.jdoProperties = jpaProperties;
            return this;
        }

        public JdoPersistenceStrategyBuilder unit(String unit) {
            this.unit = unit;
            return this;
        }

        public JdoPersistenceStrategyBuilder annotatedWith(Class<? extends Annotation> annotation) {
            this.annotation = annotation;
            return this;
        }

        public JdoPersistenceStrategy build() {
            return new JdoPersistenceStrategy(this);
        }
    }
}


text:
package net.ontopia.topicmaps.impl.utils;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;

import net.ontopia.utils.LookupIndexIF;

/**
 * INTERNAL: A lookup index that transforms its entry values to and
 * from SoftReferences. Storage of the actual value is delegated to
 * the nested index.
 */

@Deprecated
public class StatisticsIndex<K, V> implements LookupIndexIF<K, V> {

  protected int total;
  protected int hits;
  protected int misses;
  protected int misses_deref;

  protected String name;
  protected LookupIndexIF<K, Reference<V>> index;

  public StatisticsIndex(String name, LookupIndexIF<K, Reference<V>> index) {
    this.name = name;
    this.index = index;
  }

  @Override
  public V get(K key) {
    total++;

    Object retval = index.get(key);
    if (retval == null)
      misses++;
    else {
      retval = ((Reference<V>)retval).get();
      if (retval == null)
	misses_deref++;
    }

    if (retval != null) hits++;

    if (total % 1000 == 0) dump();
    return (V)retval;
  }

  @Override
  public V put(K key, V value) {
    Reference<V> retval = index.put(key, new SoftReference<V>(value));
    if (retval == null)
      return null;
    else
      return retval.get();
  }

  @Override
  public V remove(K key) {
    Reference<V> retval = index.remove(key);
    if (retval == null)
      return null;
    else
      return retval.get();
  }

  protected int percent(int c, int total) {
    if (c == 0) return 0;
    return Math.round(((100.0f*c)/(1.0f*total)));
  }

  public void dump() {
    System.out.println("StatisticsIndex: " + name);
    System.out.println("  hits: " + hits + " (" + percent(hits, total) + "%)");
    System.out.println("  misses: " + misses + " (" + percent(misses, total) + "%)");
    System.out.println("  misses deref: " + misses_deref + " (" + percent(misses_deref, total) + "%)");
  }

}