#// Content-Type: text/plain; charset=utf-8

#// bashlib is provided under 3-clause BSD license.
#// Copyright (C) 2011 Sofrware Design Gallery "Sage Plaisir 21" All Rights Reserved.


 
#//*********************************************************************
#// <<< [declare_AssociativeArrayClass] >>> 
#//*********************************************************************
if [ "${BASH_VERSINFO[0]}" -ge "4" ];then
  declare_AssociativeArrayClass="declare -A"  #// bash ver4
else
  declare_AssociativeArrayClass="declare"  #// bash ver3
fi


 
#//*********************************************************************
#// <<< [CallMain_func] >>> 
#//*********************************************************************
function  CallMain_func()
{
  local  is_not_err_handled=0

  trap 'set +x ; ErrTrap_func' EXIT
  trap 'set +x ; ErrTrap_func $LINENO ;  break' ERR  #// In function, it is necessary to bash -E option
  trap 'DebugTrap_func  "$LINENO"  "$BASH_COMMAND"  "${PIPESTATUS[@]}"
    #// resume ${PIPESTATUS[@]}
    case "${#g_PipeStatus[@]}" in
      "2")
        return ${g_PipeStatus[0]} | true;;
      "3")
        return ${g_PipeStatus[0]} | return ${g_PipeStatus[1]} | true;;
    esac' DEBUG
  set +e

  GetAbsPath_func  "`basename "${g_Arguments[0]}"`" ; g_Arguments[0]="$g_Ret"

  while TryStart_func; do

    Main_func  ""  "AppKey4293"

    g_DebugTrapFunc=""
    if [ "$g_ExitStatus" != "0" ];then  is_not_err_handled=1  ;fi
  TryEnd1_func; done ;TryEnd2_func $?
  g_DebugTrapFunc=""

  if [ "$g_ExitStatus" != "0" ];then
    if [ "$g_Err_Desc" == "" ];then
      ColorText_func  "<ERROR/>"  "Red" "Bold"
    else
      ColorText_func  "$g_Err_Desc"  "Red" "Bold"
    fi
    echo_e_func  "$g_Ret" >&2
    echo "Exit Status = $g_ExitStatus"  >&2
    echo_line_func
    echo -n "$g_Err_ErrCallStack"  >&2
    if [ "$g_Err_Desc" == "" ];then
      echo  "<ERROR/>"  >&2
    else
      echo  "$g_Err_Desc"  >&2
    fi
    if [ "$is_not_err_handled" == "1" ];then
      echo  "エラー処理がされていません。ErrClass.clear_method または ErrClass.raiseOverwrite_method を呼び出してください"
    fi
    trap ':' EXIT
    exit  "$g_ExitStatus"
  fi
  trap ':' EXIT
}


 
#//*********************************************************************
#// <<< [DebugTrap_func] >>> 
#//*********************************************************************
function  DebugTrap_func()
{
  if [ "$g_DebugTrapFunc" == "" ];then
    shift  2
    g_PipeStatus=( "$@" )
  else
    $g_DebugTrapFunc  "$@"
  fi
}


 
#//*********************************************************************
#// <<< [EchoOn_func] >>> 
#//*********************************************************************
function  EchoOn_func()
{
  echo  "${BASH_LINENO[0]}: EchoOn_func at ${FUNCNAME[1]}() in ${BASH_SOURCE[1]}" >&2

  g_DebugTrapFunc="EchoOnTrap_func"

  trap 'DebugTrap_func  "$LINENO"  "$BASH_COMMAND"  "${PIPESTATUS[@]}"
    #// resume ${PIPESTATUS[@]}
    case "${#g_PipeStatus[@]}" in
      "2")
        return ${g_PipeStatus[0]} | true;;
      "3")
        return ${g_PipeStatus[0]} | return ${g_PipeStatus[1]} | true;;
    esac' DEBUG
}

function  EchoOnTrap_func()
{
  local  LineNo="$1"
  local  Command="$2"
  shift  2
  g_PipeStatus=( "$@" )

  echo "$LineNo: $Command" >&2
}


 
#//*********************************************************************
#// <<< [EchoOff_func] >>> 
#//*********************************************************************
function  EchoOff_func()
{
  g_DebugTrapFunc=""
}


 
#//*********************************************************************
#// <<< [echo_line_func] >>> 
#//*********************************************************************
function  echo_line_func()
{
  echo "-------------------------------------------------------------------------------"
}


 
#//*********************************************************************
#// <<< [Pause_func] >>> 
#//*********************************************************************
function  Pause_func()
{
  local  Param="$1"
  local  key
  local  sec

  if [ "$Param" != "" ];then
    local  arguments
    $declare_AssociativeArrayClass  option

    GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option
    Attr_func  option  "time_out" ; sec="$g_Ret"
    AssociativeArrayClass.destroy_method  option
  fi

  if [ "$sec" == "" ];then
    read -p "続行するには Enter キーを押してください . . ."  key
  else
    for (( sec = $sec; sec >=0; sec -- )) ;do
      echo -e -n "\r"
      if [ "$sec" == "0" ];then
        echo  "続行するには Enter キーを押してください . . .  "
        break
      fi

      read -p "続行するには Enter キーを押してください . . . $sec " -t 1  key || key="...."
      if [ "$key" == "" ];then  break  ;fi
    done ; done_func $?
  fi
}


 
#//*********************************************************************
#// <<< [ColorText_func] >>> 
#//*********************************************************************
function  ColorText_func()
{
  local  Text="$1"
  shift  1
  local  ColorNames=("$@")
  local  i
  local  n
  local  str

  #//=== initialize  g_ColorText_Codes
  Attr_func  g_ColorText_Codes  "Black"
  if [ "$g_Ret" == "" ];then

    #//=== set escape sequence
    SetAttr_func  g_ColorText_Codes  "Black"    30
    SetAttr_func  g_ColorText_Codes  "Red"      31
    SetAttr_func  g_ColorText_Codes  "Green"    32
    SetAttr_func  g_ColorText_Codes  "Yellow"   33
    SetAttr_func  g_ColorText_Codes  "Blue"     34
    SetAttr_func  g_ColorText_Codes  "Magenta"  35
    SetAttr_func  g_ColorText_Codes  "Cyan"     36
    SetAttr_func  g_ColorText_Codes  "White"    37

    SetAttr_func  g_ColorText_Codes  "BlackBack"    40
    SetAttr_func  g_ColorText_Codes  "RedBack"      41
    SetAttr_func  g_ColorText_Codes  "GreenBack"    42
    SetAttr_func  g_ColorText_Codes  "YellowBack"   43
    SetAttr_func  g_ColorText_Codes  "BlueBack"     44
    SetAttr_func  g_ColorText_Codes  "MagentaBack"  45
    SetAttr_func  g_ColorText_Codes  "CyanBack"     46
    SetAttr_func  g_ColorText_Codes  "WhiteBack"    47

    SetAttr_func  g_ColorText_Codes  "Bold"  1
  fi

  str="\e["
  n=$(( ${#ColorNames[@]} - 1 ))
  for (( i = 0;  i <= n;  i++ )) ;do
    Attr_func  g_ColorText_Codes  "${ColorNames[$i]}"
    if [ "$i" == "$n" ];then
      str="${str}${g_Ret}m"
    else
      str="${str}${g_Ret};"
    fi
  done ; done_func $?

  g_Ret="${str}${Text}\e[m"
}

$declare_AssociativeArrayClass  g_ColorText_Codes


 
#//*********************************************************************
#// <<< [echo_e_func] >>>
#//*********************************************************************
function  echo_e_func()
{
  local  Text="$@"
  eval echo '$'"'$Text'"
}


 
#//*********************************************************************
#// <<< [Input_func] >>> 
#//*********************************************************************
function  Input_func()
{
  local  Prompt="$1"
  local  key
  local  ifs_bk

  if [ "$Prompt" == "" ];then  Prompt=">"  ;fi

  if [ "$g_AutoInput_ArgsNextIndex" -lt "${#g_AutoInput_Args[@]}" ];then
    key="${g_AutoInput_Args[$g_AutoInput_ArgsNextIndex]}"
    g_Ret="$key"
    echo  "$Prompt$key"
    g_AutoInput_ArgsNextIndex=$(( $g_AutoInput_ArgsNextIndex + 1 ))
  else
    ifs_bk="$IFS"
    IFS="\\"  #// This can input space or tab at the end of string
    read -p "$Prompt" -r g_Ret
    IFS="$ifs_bk"
  fi
}


 
#//*********************************************************************
#// <<< [SetAutoInputFromMainArg_func] >>> 
#//*********************************************************************
g_AutoInput_Args=( )
g_AutoInput_ArgsNextIndex=0

function  SetAutoInputFromMainArg_func()
{
  g_AutoInput_Args=( "${g_Arguments[@]}" )
  g_AutoInput_ArgsNextIndex=1
}


 
#//*********************************************************************
#// <<< [InputPath_func] >>> 
#//*********************************************************************
function  InputPath_func()
{
  local  Prompt="$1"
  local  input_path
  local  base_path
  local  is_file_exist_opt
  local  is_folder_exist_opt
  local  is_not_exist_opt
  local  len
  local  ret
  local  arguments
  $declare_AssociativeArrayClass  options

  GetLongOptions_func  arguments  options  "$@"  #//[out] arguments, options

  while true; do
    Input_func  "$Prompt$base_path" ; input_path="$g_Ret"

    if [ "$base_path$input_path" == "" ]; then
      Attr_func  options  "AllowEnterOnly"
      if [ "$g_Ret" == "1" ]; then
        ret=""
        break
      fi

    else

      StringClass.right_method  "$input_path"  1
      if [ "$g_Ret" == "$Tab" ];then

        StringClass.length_method  "$input_path"
        len=$(( $g_Ret - 1 ))
        StringClass.substring_method  "$input_path"  0  "$len" ; input_path="$g_Ret"
        InputPathSelectSub_func  "$input_path"  "$base_path"  base_path  #//[out] base_path

      else

        if [ "$base_path" != "" ];then
          input_path="$base_path$input_path"
        fi
        StringClass.substring_method  "$input_path"  0  1
        if [ "$g_Ret" == "~" ];then
          StringClass.replace_method  "$input_path"  "~"  "$HOME" ; input_path="$g_Ret"
        fi
        eval "input_path=\"$input_path\""
        GetAbsPath_func  "$input_path"  "$g_StartInPath" ; input_path="$g_Ret"

        Attr_func  options  "ChkFileExists" ; is_file_exist_opt="$g_Ret"
        Attr_func  options  "ChkFolderExists" ; is_folder_exist_opt="$g_Ret"
        Attr_func  options  "ChkNotExists" ; is_not_exist_opt="$g_Ret"

        if [ "$is_not_exist_opt" == "1" ];then
          Assert_func  '"$is_file_exist_opt" != "1"'
          Assert_func  '"$is_folder_exist_opt" != "1"'
        fi

        if [ x"$is_file_exist_opt" == x""  -a \
             x"$is_folder_exist_opt" == x""  -a \
             x"$is_not_exist_opt" == x"" ];then
          ret="$input_path"
          break
        fi

        if [ "$is_not_exist_opt" == "1" ];then
          if [ -f "$input_path" ]; then
            echo  "すでにファイルが存在しています。" >&2
          elif [ -d "$input_path" ]; then
            echo  "すでにフォルダーが存在しています。" >&2
          else
            ret="$input_path"
            break
          fi
        else
          if [ "$is_file_exist_opt" == "1" ];then
            if [ -f "$input_path" ]; then
              ret="$input_path"
              break
            fi
          fi

          if [ "$is_folder_exist_opt" == "1" ];then
            if [ -d "$input_path" ]; then
              ret="$input_path"
              break
            fi
          fi

          if [ "$is_file_exist_opt" == "1" ];then
            if [ "$is_folder_exist_opt" == "1" ];then
              echo  "ファイルまたはフォルダーが見つかりません。" >&2
            else
              echo  "ファイルが見つかりません。" >&2
            fi
          else
            echo  "フォルダーが見つかりません。" >&2
          fi
        fi
        echo  "$input_path" >&2
      fi
    fi
  done ; done_func $?
  AssociativeArrayClass.destroy_method  options
  g_Ret="$ret"
}

function  InputPathSelectSub_func()
{
  local  PartOfPath="$1"
  local  BasePath="$2"
  local  out_SelectedPath="$3"
  local  folder
  local  paths
  local  paths2
  local  i
  local  path
  local  part_of_file
  local  len
  local  num
  local  new_base_path

  if [ "$BasePath" != "" ];then
    PartOfPath="$BasePath$PartOfPath"
  fi
  LeftOfLastStr_func  "$PartOfPath"  "/" ; folder="$g_Ret"
  if [ x"$folder" == x""  -o  x"$folder" == x"$PartOfPath" ];then
    folder="."
  else
    new_base_path="$folder/"
  fi
  StringClass.substring_method  "$folder"  0  1
  if [ "$g_Ret" == "~" ];then
    StringClass.replace_method  "$folder"  "~"  "$HOME" ; folder="$g_Ret"
  fi
  eval "folder=\"$folder\""

  RightOfLastStr_func  "$PartOfPath"  "/" ; part_of_file="$g_Ret"

  unset paths
  pushd  "$g_StartInPath" > /dev/null
  paths=`ls -p1A "$folder"`
  popd  > /dev/null
  ArrayClass.fromLines_method  paths  "$paths"  #//[out] paths

  i=0
  StringClass.length_method  "$part_of_file" ; len="$g_Ret"
  for path  in "${paths[@]}" ;do
    StringClass.substring_method  "$path"  0  "$len"
    if [ "$g_Ret" == "$part_of_file" ];then
      paths2[$i]="$path"
      i=$(( $i + 1 ))
    fi
  done ; done_func $?

  if [ "$PartOfPath" == "" ];then
    echo  "$g_StartInPath/"
  else
    GetAbsPath_func  "$PartOfPath"  "$g_StartInPath"
    echo  "$g_Ret"
  fi
  for (( i = 0; i < ${#paths2[@]}; i ++ ));do
    echo -n "$(( $i + 1 )). ${paths2[$i]}   "
  done ; done_func $?
  echo -n "88. クリア   99. 戻る"

  while true; do
    Input_func  "  >" ; num="$g_Ret"
    if [ "$num" == "88" ];then
      SetOutput_func  "$out_SelectedPath"  ""
      break
    elif [ x"$num" == x"99"  -o  x"$num" == x"" ];then
      SetOutput_func  "$out_SelectedPath"  "$BasePath"
      break
    elif [ "$num" -le "$i"  -a  "$num" -ge "0" ];then
      if [ "$new_base_path" == "" ];then
        SetOutput_func  "$out_SelectedPath"  "${paths2[$(( $num - 1 ))]}"
      else
        SetOutput_func  "$out_SelectedPath"  "$new_base_path${paths2[$(( $num - 1 ))]}"
      fi
      break
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [InputCommand_func] >>> 
#//*********************************************************************
function  InputCommand_func()
{
  local  self="$1"
  local  Prompt="$2" ; if [ "$Prompt" == "" ];then  Prompt="番号またはコマンド >"  ;fi
  local  Opt="$3"
  local  AppKey="$4"

  local  replaces
  local  key
  local  num
  local  func
  local  is_prompt
  local  current_folder=`pwd`
  local  captions
  local  caption
  local  a1


  SetAutoInputFromMainArg_func
  if [ "${#g_Arguments[@]}" == "1" ];then  is_prompt=1  ;else  is_prompt=0  ;fi

  Attr_func  $self  CommandReplace ; replaces="$g_Ret"
  Attr_func  $self  MenuCaption ; captions="$g_Ret"

  while true; do

    #//=== show menu
    if [ "$is_prompt" != "0" ];then
      echo_line_func
      echo  "$g_StartInPath>"
      Attr_func  $self  Lead
      echo  "$g_Ret"

      AssociativeArrayClass.getKeys_method "$replaces" ; a1="$g_Ret"
      for key  in $a1 ;do
        IsNumeric_func $key ; if [ "$g_Ret" == "1" ]; then
          Attr_func  $captions  $key ; caption="$g_Ret"
          if [ "$caption" == "" ];then
            Attr_func  $replaces  $key
            echo  "$key. $g_Ret"
          else
            echo  "$key. $caption"
          fi
        fi
      done ; done_func $?
      echo  "99. 終了"

      while true; do
        Input_func  "$Prompt" ; num="$g_Ret"
        if [ "$num" != "" ];then  break  ;fi
      done ; done_func $?
      echo_line_func
    else
      while true; do
        Input_func  "$Prompt" ; num="$g_Ret"
        if [ "$num" != "" ];then  break  ;fi
      done ; done_func $?
    fi
    if [ "$num" == "99" ];then
      a1=`basename "${g_Arguments[0]}"`
      echo  "（ヒント）$a1 のパラメーターに、入力する内容を指定できます。"
      break
    fi

    #//=== call
    Attr_func  $replaces  "$num" ; func="$g_Ret"
    if [ "$func" != "" ];then  num="$func" ; Attr_func  $replaces  $func ; func="$g_Ret"  ;fi
    if [ "$func" == "" ];then  func="$num"  ;fi
    echo  " ((( $func )))"

    if [ "$is_prompt" != "0" ];then
      while TryStart_func; do
        StringClass.right_method  "$func"  5
        if [ "$g_Ret" == "_func" ];then
          $func  "$Opt"  "$AppKey"
        else
          echo "$PWD\$ $func"
          eval $func  #// eval is for reference variables
        fi
      TryEnd1_func; done ;TryEnd2_func $?
      EchoOff_func
      if [ "$g_ExitStatus" != "0" ];then
        echo  "Exit Status = $g_ExitStatus"
        if [ "$g_Err_Desc" == "" ];then
          ColorText_func  "<ERROR/>"  "Red" "Bold"
        else
          ColorText_func  "$g_Err_Desc"  "Red" "Bold"
        fi
        echo_e_func  "$g_Ret"  >&2
        if [ "$g_Err_Desc" == "" ];then
          echo  "${g_Err_ErrCallStack}<ERROR/>"  >&2
        else
          echo  "${g_Err_ErrCallStack}${g_Err_Desc}"  >&2
        fi
        if [ "$is_not_err_handled" == "1" ];then
          echo  "エラー処理がされていません。ErrClass.clear_method または ErrClass.raiseOverwrite_method を呼び出してください"  >&2
        fi
      fi
      ErrClass.clear_method
    else
      "$func"  "$Opt"  "$AppKey"
      break
    fi
    cd  "$current_folder"
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [InputOption_func] >>> 
#//*********************************************************************
function  InputOption_func()
{
  local  name__
  local  key__
  local  left__
  local  right__
  local  comments__
  local  i__
  local  is_err__

  local  Options__
  $declare_AssociativeArrayClass  option__

  GetLongOptions_func  Options__  option__  "$@"  #//[out] arguments__, option__
  Attr_func  option__  comment
  ArrayClass.fromCSV_method  comments__  "$g_Ret"  #//[out] comments__

  SetAutoInputFromMainArg_func

  while true ;do

    #// finish auto input
    if [ "$g_AutoInput_ArgsNextIndex" -ge "${#g_AutoInput_Args[@]}"  -a \
         "$g_AutoInput_ArgsNextIndex" -ge "2"  -a \
         "$is_err__" != "1"  ];then
      break
    fi

    echo  ""
    echo  "現在のオプション設定："
    i__=0
    for  name__  in  "${Options__[@]}" ;do
      eval echo  "--$name__="'"\"$'"$name__"'\"  ${comments__[$i__]}"'
      i__=$(( $i__ + 1 ))
    done ; done_func $?
    echo  "Enter または . ：設定完了"
    Input_func  "オプションを入力してください（例：--${Options__[0]}=\"abc\"、--flag）>"
    key__="$g_Ret"
    if [ x"$key__" == x""  -o  x"$key__" == x"." ];then  break  ;fi

    if [ "${key__:0:2}" == "--" ];then
      key__="${key__:2}"
    elif [ "${key__:0:1}" == "-" ];then
      key__="${key__:1}"
    fi
    LeftOfStr_func  "$key__"  "=" ; left__="$g_Ret"
    if [ "$key__" == "$left__" ];then
      right__="1"
    else
      RightOfStr_func "$key__"  "=" ; eval right__="$g_Ret"
    fi

    for  name__  in  "${Options__[@]}" ;do
      if [ "$name__" == "$left__" ];then
        SetOutput_func  $name__  "$right__"
        unset  left__
        break
      fi
    done ; done_func $?
    if [ "$left__" != "" ];then
      echo  "オプション $left__ はありません。"
      is_err__="1"
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [sudo_func] >>> 
#//*********************************************************************
function  sudo_func()
{
  g_TemporarySudo="sudo"
  "$@"
  unset  g_TemporarySudo
}


 
#//*********************************************************************
#// <<< [mkdir_for_it_func] >>> 
#//*********************************************************************
function  mkdir_for_it_func()
{
  local  FilePath="$1"
  CheckArgCount_func  1 "$@"

  folder_path=${FilePath%/*}  #// parent folder
  if [ "$folder_path" == "$FilePath" ]; then  return 0  ;fi  #// if not found "/"
  if [ ! -f "$folder_path" ]; then  mkdir -p  "$folder_path"  ;fi
}


 
#//*********************************************************************
#// <<< [readlink_func] >>> 
#//*********************************************************************
function  readlink_func()
{
  local  LinkPath="$1"
  CheckArgCount_func  1 "$@"

  if [ "$g_is_readlink_f" == "" ];then
    while TryStart_func; do
      g_Ret=`readlink -f "$LinkPath" 2> /dev/null`
    TryEnd1_func; done ;TryEnd2_func $?
    if [ "$g_ExitStatus" == "0" ]; then  g_is_readlink_f=1 ; return  ;fi
    ErrClass.clear_method
    g_is_readlink_f=0
  fi

  if [ "$g_is_readlink_f" == "1" ];then
    g_Ret=`readlink -f "$LinkPath"`
  else
    local  folder
    local  ph_folder
    local  name
    local  ph_name

    folder=`dirname "$LinkPath"`
    if [ "$folder" != "" ];then  pushd  "$folder" > /dev/null ;fi
    ph_folder=`pwd -P`

    name=`basename  "$LinkPath"`
    ph_name=`readlink  "$name"` || :
    if [ "$ph_name" == "" ];then
      g_Ret="$ph_folder/$name"
    else
      g_Ret="$ph_folder/$ph_name"
    fi
    if [ "$folder" != "" ];then  popd > /dev/null ;fi
  fi
}

g_is_readlink_f=""


 
#//*********************************************************************
#// <<< [GetAbsPath_func] >>> 
#//*********************************************************************
function  GetAbsPath_func()
{
  local  StepPath="$1"
  local  BasePath="$2"
  CheckMinArgCount_func  1 "$@"
  CheckMaxArgCount_func  2 "$@"

  local  abs_path
  local  str

  LeftOfStr_func "$StepPath" "/" ; str="$g_Ret"  #// if abs path, str=""
  if [ "$str" == "" ]; then
    g_Ret="$StepPath"
  elif [ "$str" == "~" ]; then
    StringClass.substring_method  "$StepPath"  1
    g_Ret="$HOME$g_Ret"
  else
    if [ "$BasePath" == "" ];then  BasePath="$PWD"  ;fi

    abs_path="$BasePath/$StepPath"

    while true; do   #//  "*/../" -> ""
      echo  "$abs_path" | grep  "[^/]*/\.\./" > /dev/null  || break
      abs_path=`echo "$abs_path" | sed -e "s%[^/]*/\.\./%%"`
    done ; done_func $?

    while true; do   #//  "/*/.." -> ""
      echo  "$abs_path" | grep  "[^/]*/[^/]*/\.\." > /dev/null  || break
      abs_path=`echo "$abs_path" | sed -e "s%/[^/]*/\.\.$%%"`
    done ; done_func $?

    while true; do  #//  "/./" -> "/"
      echo  "$abs_path" | grep  "/\./" > /dev/null  || break
      StringClass.replace_method  "$abs_path"  "/./"  "/" ; abs_path="$g_Ret"
    done ; done_func $?

    while true; do  #//  "/." -> ""
      StringClass.right_method  "$abs_path"  2
      if [ "$g_Ret" != "/." ];then  break  ;fi
      StringClass.replace_method  "$abs_path"  "/./"  "/" ; abs_path="$g_Ret"
      abs_path=`echo "$abs_path" | sed -e "s%/\.$%%"`
    done ; done_func $?

    g_Ret="$abs_path"
  fi
}


 
#//*********************************************************************
#// <<< [GetParentAbsPath_func] >>> 
#//*********************************************************************
function  GetParentAbsPath_func()
{
  local  Path="$1"
  CheckArgCount_func  1 "$@"

  local  str

  LeftOfStr_func "$Path" "/" ; str="$g_Ret"  #// if abs path, str=""
  if [ "$str" != "" ]; then
    GetAbsPath_func "$Path" ; Path="$g_Ret"
  fi

  if [ x"$Path" == x"/"  -o  x"$Path" == x"" ]; then
    g_Ret="$Path"
  else
    RightOfLastStr_func "$Path" "/"  #// if last char is "/", str=""
    if [ "$g_Ret" == "" ]; then
      LeftOfLastStr_func "$Path" "/" ; Path="$g_Ret"
    fi
    LeftOfLastStr_func  "$Path"  "/" ; Path="$g_Ret"  #// parent folder
    if [ "$Path" == "" ];then  Path="/"  ;fi
    g_Ret="$Path"
  fi
}


 
#//*********************************************************************
#// <<< [SearchParent_func] >>>
#//*********************************************************************
function  SearchParent_func()
{
  local  path="$1"
  local  folder
  local  file

  GetAbsPath_func  "$path"  "$PWD" ; path="$g_Ret"
  if [ -e "$path" ];then  g_Ret="$path" ; return ;fi

  folder=`dirname  "$path"`
  file=` basename  "$path"`
  while true; do
    folder=`dirname  "$folder"`
    if [ "$folder" == "/" ];then  break  ;fi
    if [ -e "$folder/$file" ];then  g_Ret="$folder/$file" ; return ;fi
  done ; done_func $?
  if [ -e "/$file" ];then  g_Ret="/$file" ; return ;fi
  g_Ret=""
}


 
#//*********************************************************************
#// <<< [local_func] >>> 
#//*********************************************************************
function  local_func()
{
  local  arguments
  $declare_AssociativeArrayClass  option
  local  args
  local  locals
  local  param
  local  name
  local  code
  local  arg_num=0
  local  out_names=( )
  local  a1
  local  a2

  GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option

  Attr_func  option  "arg"
  ArrayClass.fromCSV_method  args  "$g_Ret"  #//[out] args

  Attr_func  option  "local"
  ArrayClass.fromCSV_method  locals  "$g_Ret"  #//[out] locals

  for param  in ${args[@]}  ;do
    StringClass.substring_method  "$param"  0 5 ; a1="$g_Ret"
    StringClass.substring_method  "$param"  0 8 ; a2="$g_Ret"
    if [ "$a1" == "(out)" ];then 
      StringClass.substring_method  "$param"  5 ; param="$g_Ret"
      out_names=( "${out_names[@]}" "${arguments[$arg_num]}" )
    elif [ "$a2" == "(in_out)" ];then
      StringClass.substring_method  "$param"  8 ; param="$g_Ret"
      out_names=( "${out_names[@]}" "${arguments[$arg_num]}" )
    fi
    arg_num=$(( $arg_num + 1 ))
    code="$code  local  $param=\""'$'"$arg_num\";"
  done ; done_func $?

  for param  in "${locals[@]}"  ;do
    code="$code  local  $param;"
  done ; done_func $?

  locals=( "${args[@]}"  "${locals[@]}" )

  for name  in ${out_names[@]} ;do
    for param  in "${locals[@]}" ;do
      if [ "$name" == "$param" ];then
        AssociativeArrayClass.destroy_method  option
        Error_func  "<ERROR msg=\"出力引数がローカル変数名と衝突しています\" name=\"$name\"/>"
      fi
    done ; done_func $?
  done ; done_func $?

  AssociativeArrayClass.destroy_method  option
  g_Ret="$code"
}


 
#//*********************************************************************
#// <<< [GetUsableCommands_func] >>> 
#//*********************************************************************
function  GetUsableCommands_func()
{
  local  out_FoundCommands="$1"
  shift  1
  local  Commands=( "$@" )
  local  command
  local  is_found
  local  founds=( )

  for command  in ${Commands[@]} ;do
    while TryStart_func; do
      which $command > /dev/null
    TryEnd1_func; done ;TryEnd2_func $?
    if [ "$g_ExitStatus" == "0" ];then  founds=( "${founds[@]}"  "$command " )  ;fi
    ErrClass.clear_method
  done ; done_func $?
  SetOutputAsArray_func  $out_FoundCommands  "${founds[@]}"
}


 
#//*********************************************************************
#// <<< [GetUsableApplicationsForMac_func] >>> 
#//*********************************************************************
function  GetUsableApplicationsForMac_func()
{
  local_func \
    --arg="  (out)out_FoundCommands "  \
    --local=" command__, commands__, apps__, app__, path__, file_name__, paths__, i__ " \
    "$@" ; eval  "$g_Ret"
    #// --arg="Applications ..."
  apps__=( )
  shift  1
  local  Applications=( "$@" )

  #// list up applications
  while TryStart_func; do
    paths__=`ls /Applications/*.app /Applications/Utilities/*.app 2>/dev/null | grep :$`
  TryEnd1_func; done ;TryEnd2_func $?
  if [ "$g_ExitStatus" != "0" ]; then
    unset  $out_FoundCommands
    unset  $out_FoundCommands  #// 配列をクリアするには２回必要？
    ErrClass.clear_method
    return  0
  fi
  ArrayClass.fromLines_method  paths__  "$paths__"  #//[out] paths__

  i__=0
  for path__  in "${paths__[@]}" ;do
    file_name__=`basename "$path__"`
    LeftOfLastStr_func  "$file_name__"  ".app:" ; apps__[$i__]="$g_Ret"
    i__=$(( $i__ + 1 ))
  done ; done_func $?

  if [ "${#Applications[@]}" == "0" ];then
    for (( i__ = 0; i__ < ${#apps__[@]}; i__ ++ )) ;do
      apps__[$i__]="open -a \"$apps__[$i__]\" "
    done ; done_func $?
    SetOutputAsArray_func  $out_FoundCommands  "${apps__[@]}"
    return  0
  fi

  #// pick up applications
  i__=0
  for command__  in "${Applications[@]}" ;do
    for app__  in "${apps__[@]}" ;do
      if [ "$command__" == "$app__" ];then
        commands__[$i__]="open -a \"$app__\" "
        i__=$(( $i__ + 1 ))
        break
      fi
    done ; done_func $?
  done ; done_func $?
  if [ "$i__" == "0" ];then  ArrayClass.clear_method  commands__  ;fi  #// because local sets ${#commands__[@]}=1
  SetOutputAsArray_func  $out_FoundCommands  "${commands__[@]}"
}


 
#//*********************************************************************
#// <<< [IsMac_func] >>> 
#//*********************************************************************
function  IsMac_func()
{
  SystemClass.getProperty_method  "os.name"
  StringClass.indexOf_method  "$g_Ret"  "Mac OS X"
  if [ "$g_Ret" == "-1" ];then
    g_Ret=0
  else
    g_Ret=1
  fi
}


 
#//*********************************************************************
#// <<< [SystemClass.getProperty_method] >>> 
#//*********************************************************************
function  SystemClass.getProperty_method()
{
  local  PropertyName="$1"

  if [ "$PropertyName" == "os.name" ];then
    if [ -e "/Applications/App Store.app" ];then
      g_Ret="Mac OS X ..."
    else
      g_Ret="Linux ..."
    fi
  else
    Error_func
  fi
}


 
#//*********************************************************************
#// <<< [IsInstalled_func] >>>
#//*********************************************************************
function  IsInstalled_func()
{
  local  PackageSymbol="$1"

  local  status=0
  dpkg -l "$PackageSymbol" | grep ^ii\ *"$PackageSymbol" > /dev/null|| status=$?
  if [ "$status" == "0" ];then
    g_Ret=1
  else
    g_Ret=0
  fi
}


 
#//*********************************************************************
#// <<< [AppKeyClass.enableInstall_method] >>>
#//*********************************************************************
function  AppKeyClass.enableInstall_method()
{
  local  AppKey="$1"

  if [ "$AppKey" != "AppKey4293" ]; then  Error_func  "AppKeyClass.enableInstall_method needs \$2 of Main_func"  ;fi

  g_IsEnableInstall3192="1310"
}


 
#//*********************************************************************
#// <<< [InstallIfNot_func] >>>
#//*********************************************************************
g_IsEnableInstall3192="0"

function  InstallIfNot_func()
{
  local  PackageSymbol="$1"

  IsInstalled_func  "$PackageSymbol"
  if [ "$g_Ret" == "0" ];then
    if [ "$g_IsEnableInstall3192" != "1310" ];then  #// チェックのみ
      Error_func  "apt-get が許可されていません。参照：AppKeyClass.enableInstall_method"
    else
      echo  "apt-get install  \"$PackageSymbol\""
      $g_TemporarySudo  apt-get install  "$PackageSymbol" <<HereDocument
y
HereDocument
    fi
  fi
}


 
#//*********************************************************************
#// <<< [Uninstall_func] >>>
#//*********************************************************************
function  Uninstall_func()
{
  local  PackageSymbol="$1"

  if [ "$g_IsEnableInstall3192" != "1310" ];then  #// チェックのみのときは、IsInstalled_func
    Error_func  "apt-get が許可されていません。参照：AppKeyClass.enableInstall_method"
  fi

  IsInstalled_func  "$PackageSymbol"
  if [ "$g_Ret" == "1" ];then
    echo  "apt-get remove  \"$PackageSymbol\""
    $g_TemporarySudo  apt-get remove  "$PackageSymbol" <<HereDocument
y
HereDocument
  fi
}


 
#//*********************************************************************
#// <<< [GetLongOptions_func] >>> 
#//*********************************************************************
function  GetLongOptions_func()
{
  local  out_Arguments="$1"
  local  out_OptAssocArray="$2"
  shift  2
  local  Args__=("$@")
  local  param__
  local  name__
  local  value__
  local  ArgIndex__=0

  local  locals="out_Arguments  out_OptAssocArray  Args__  param__  name__  value__  locals"
  CheckOutParamIsConflictToLocal_func  "$out_Arguments"      $locals
  CheckOutParamIsConflictToLocal_func  "$out_OptAssocArray"  $locals

  AssociativeArrayClass.clear_method  $out_OptAssocArray

  for param__  in "${Args__[@]}" ;do
    StringClass.substring_method  "$param__"  0  2
    if [ "$g_Ret" == "--" ];then
      LeftOfStr_func  "$param__"  "=" ; name__="$g_Ret"
      if [ "$name__" == "$param__" ];then
        value__="1"
      else
        RightOfStr_func  "$param__"  "=" ; value__="$g_Ret"
      fi
      StringClass.substring_method  "$name__"  2 ; name__="$g_Ret"

      SetAttr_func  $out_OptAssocArray  $name__  "$value__"
    else
      SetArrItem_func  $out_Arguments  $ArgIndex__  "$param__"
      ArgIndex__=$(( $ArgIndex__ + 1 ))
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [Attr_func] >>> 
#//*********************************************************************
function  Attr_func()
{
  local  self="$1"
  local  AttrName="$2"
  local  tmp
  CheckArgCount_func  2 "$@"

  eval  tmp="\${${self}[\$AttrName]}"
  g_Ret="$tmp"
}


 
#//*********************************************************************
#// <<< [SetArrItem_func] >>> 
#//*********************************************************************
function  SetArrItem_func()
{
  local  self__="$1"
  local  Index__="$2"
  local  Value__="$3"
  CheckArgCount_func  3 "$@"

  eval  "$self__[$Index__]=\"$Value__\""
}


 
#//*********************************************************************
#// <<< [SetAttr_func] >>> 
#//*********************************************************************
function  SetAttr_func()
{
  SetArrItem_func  "$@"
}


 
#//*********************************************************************
#// <<< [SetAttr_as_ArrayName_func] >>> 
#//*********************************************************************
function  SetAttr_as_ArrayName_func()
{
  local  self__="$1"
  local  AttrName__="$2"
  local  i__
  local  Params__
  CheckOutParamIsConflictToLocal_func  "$self__"  self__  AttrName__  i__  Params__

  shift  2
  Params__=("$@")

  SetAttr_func  $self__  "$AttrName__"  "g_Arrays_$g_ArrayLength"

  for (( i__ = 0; i__ < ${#Params__[@]}; i__ ++ ));do
    eval  "g_Arrays_$g_ArrayLength"'[$i__]'='${Params__[$i__]}'
  done ; done_func $?

  g_ArrayLength=$(( $g_ArrayLength + 1 ))
}


 
#//*********************************************************************
#// <<< [SetAttr_as_AssociativeArrayName_func] >>> 
#//*********************************************************************
function  SetAttr_as_AssociativeArrayName_func()
{
  local  self__="$1"
  local  AttrName__="$2"
  local  i__
  local  Params__
  local  key__
  local  value__
  CheckOutParamIsConflictToLocal_func  "$self__"  self__  AttrName__  i__  Params__  key__  value__

  shift  2
  Params__=("$@")

  SetAttr_func  $self__  "$AttrName__"  "g_AssociativeArrays_$g_AssociativeArrayLength"

  for (( i__ = 0; i__ < ${#Params__[@]}; i__ = i__ + 2 ));do
    key__=${Params__[$i__]}
    value__=${Params__[$i__+1]}

    SetAttr_func  g_AssociativeArrays_$g_AssociativeArrayLength  $key__  "$value__"
  done ; done_func $?

  g_AssociativeArrayLength=$(( $g_AssociativeArrayLength + 1 ))
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.getLength_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.getLength_method()
{
  local  self="$1"
  if [ "$self" == "" ];then  Error_func  "no object name"  ;fi

  eval  g_Ret='${#'"$self"'[@]}'
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.getKeys_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.getKeys_method()
{
  local  self="$1"
  if [ "$self" == "" ];then  Error_func  "no object name"  ;fi

  eval  g_Ret='${!'"$self"'[@]}'
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.getItems_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.getItems_method()
{
  local  self="$1"
  if [ "$self" == "" ];then  Error_func  "no object name"  ;fi

  eval  g_Ret='${'"$self"'[@]}'
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.clear_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.clear_method()
{
  local  self__="$1"
  local  keys__
  local  key__
  local  locals__="self__ key__ keys__  locals"
  CheckOutParamIsConflictToLocal_func  "$self__"   $locals__

  eval  keys__='${!'"$self__"'[@]}'
  for key__  in "${keys__[@]}" ;do
    if [ "$key__" != "" ];then
      unset  "$self__[$key__]"
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [AssociativeArrayClass.destroy_method] >>> 
#//*********************************************************************
function  AssociativeArrayClass.destroy_method()
{
  local  self="$1"

  unset  $self
  unset  $self
}


 
#//*********************************************************************
#// <<< [CopyArray_func] >>> 
#//*********************************************************************
function  CopyArray_func()
{
  local  DstArray__="$1"
  local  SrcArray__="$2"
  local  key__
  local  keys__
  local  code__
  local  value__
  local  locals__="DstArray__ SrcArray__ key__ keys__ code__ value__  locals"
  CheckOutParamIsConflictToLocal_func  "$DstArray__"   $locals__
  CheckOutParamIsConflictToLocal_func  "$SrcArray__"   $locals__

  code__="$DstArray__=("
  eval  keys__=( '"${!'"$SrcArray__"'[@]}"' )
  for key__  in "${keys__[@]}" ;do
    eval  value__='${'$SrcArray__'[$key__]}'
    code__="$code__ [\"$key__\"]=\"$value__\""
  done ; done_func $?
  eval  "$code__ )"
}


 
#//*********************************************************************
#// <<< [CopyArrayAttr_func] >>> 
#//*********************************************************************
function  CopyArrayAttr_func()
{
  local  self__="$1"
  local  AttrName__="$2"
  local  out_Array="$3"
  local  array_name__
  local  i__
  local  n__
  local  locals="self__  AttrName__  out_Array__  array_name__  i__  n__  locals"
  CheckOutParamIsConflictToLocal_func  "$self__"     $locals
  CheckOutParamIsConflictToLocal_func  "$out_Array"  $locals

  Attr_func  $self__  "$AttrName__" ; array_name__="$g_Ret"
  unset  $out_Array
  unset  $out_Array  #// 配列をクリアするには２回必要？

  eval  n__='${#'"$array_name__"'[@]}'

  for (( i__ = 0; $i__ < $n__; i__ ++ ));do
    eval  "$out_Array"'[$i__]=${'"$array_name__"'[$i__]}'
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [SetOutput_func] >>> 
#//*********************************************************************
function  SetOutput_func()
{
  local  out_Var="$1"
  local  Value__="$2"
  CheckArgCount_func  2 "$@"
  CheckOutParamIsConflictToLocal_func  "$out_Var"  out_Var  Value__

  eval  $out_Var="'$Value__'"
}


 
#//*********************************************************************
#// <<< [SetOutputAsArray_func] >>> 
#//*********************************************************************
function  SetOutputAsArray_func()
{
  local  out_Var="$1"
  CheckMinArgCount_func  1 "$@"
  CheckOutParamIsConflictToLocal_func  "$out_Var"  out_Var

  shift  1
  eval  $out_Var="(" '"$@"' ")"
}


 
#//*********************************************************************
#// <<< [AddIfNotExist_func] >>> 
#//*********************************************************************
function  AddIfNotExist_func()
{
  local  WholeStr="$1"
  local  AddStr="$2"
  local  Separator="$3"
  CheckArgCount_func  3 "$@"

  local  whole_str_plus="$WholeStr$Separator"
  local  str

  if [ "$AddStr" == "" ];then  echo  "$WholeStr"  ;  return  0  ;fi

  LeftOfStr_func  "$whole_str_plus"  "$AddStr$Separator" ; str="$g_Ret"
  if [ "$str" == "$whole_str_plus" ];then  #// not found
    g_Ret="$AddStr$Separator$WholeStr"
  else
    g_Ret="$WholeStr"
  fi
}


 
#//*********************************************************************
#// <<< [IsNumeric_func] >>> 
#//*********************************************************************
function  IsNumeric_func()
{
  local  Value="$1"
  CheckArgCount_func  1 "$@"
  if [ "$Value" == "-1" ];then
    g_Ret="1"
  else
    local  status=0
    expr  $Value + 1 > /dev/null  2>&1 || status=$?
    if [ "$status" == "0" ];then
      g_Ret="1"
    else
      g_Ret="0"
    fi
  fi
}


 
#//*********************************************************************
#// <<< [StringClass.length_method] >>> 
#//*********************************************************************
function  StringClass.length_method()
{
  local  self="$1"
  CheckArgCount_func  1 "$@"
  g_Ret="${#self}"
}


 
#//*********************************************************************
#// <<< [StringClass.substring_method] >>> 
#//*********************************************************************
function  StringClass.substring_method()
{
  local  self="$1"
  local  StartIndex="$2"
  local  EndIndex="$3"
  CheckMinArgCount_func  2 "$@"
  CheckMaxArgCount_func  3 "$@"

  if [ "$EndIndex" == "" ];then
    g_Ret="${self:$StartIndex}"
  else
    g_Ret="${self:$StartIndex:$(( $EndIndex - $StartIndex ))}"
  fi
}


 
#//*********************************************************************
#// <<< [StringClass.trim_method] >>> 
#//*********************************************************************
function  StringClass.trim_method()
{
  local  String="$1"
  local  field
  local  key
  local  index
  local  ch

  index=0
  while true ;do
    ch="${String:$index:1}"
    if [ "$ch" != " "  ];then
      if [ "$ch" != "$Tab" ];then
        if [ "$ch" != "$LF" ];then
          break
        fi
      fi
    fi
    index=$(( $index + 1 ))
  done ; done_func $?

  String="${String:$index}"

  index=$(( ${#String} - 1 ))
  while true ;do
    ch="${String:$index:1}"
    if [ "$ch" != " " ];then
      if [ "$ch" != "$Tab" ];then
        if [ "$ch" != "$LF" ];then
          break
        fi
      fi
    fi
    index=$(( $index - 1 ))
  done ; done_func $?
  index=$(( $index + 1 ))

  g_Ret="${String:0:$index}"
}


 
#//*********************************************************************
#// <<< [StringClass.right_method] >>> 
#//*********************************************************************
function  StringClass.right_method()
{
  local  String="$1"
  local  Length="$2"
  CheckArgCount_func  2 "$@"

  g_Ret="${String:$(( ${#String} - $Length ))}"
}


 
#//*********************************************************************
#// <<< [StringClass.cutLastOf_method] >>> 
#//*********************************************************************
function  StringClass.cutLastOf_method()
{
  local  String="$1"
  local  LastStr="$2"
  CheckArgCount_func  2 "$@"

  if [ "${String:$(( ${#String} - ${#LastStr} ))}" == "$LastStr" ];then
    g_Ret="${String:0:$(( ${#String} - ${#LastStr} ))}"
  else
    g_Ret="$String"
  fi
}


 
#//*********************************************************************
#// <<< [LeftOfStr_func] >>> 
#//*********************************************************************
function  LeftOfStr_func()
{
  local  String="$1"
  local  Key="$2"
  CheckArgCount_func  2 "$@"

  StringClass.replace_method  "$Key"    '\'  '\\'
  StringClass.replace_method  "$g_Ret"  '*'  '\*'

  g_Ret="${String%%$g_Ret*}"
}


 
#//*********************************************************************
#// <<< [LeftOfLastStr_func] >>> 
#//*********************************************************************
function  LeftOfLastStr_func()
{
  local  String="$1"
  local  Key="$2"
  CheckArgCount_func  2 "$@"

  StringClass.replace_method  "$Key"    '\'  '\\'
  StringClass.replace_method  "$g_Ret"  '*'  '\*'

  g_Ret="${String%$g_Ret*}"
}


 
#//*********************************************************************
#// <<< [RightOfStr_func] >>> 
#//*********************************************************************
function  RightOfStr_func()
{
  local  String="$1"
  local  Key="$2"
  CheckArgCount_func  2 "$@"

  StringClass.replace_method  "$Key"    '\'  '\\'
  StringClass.replace_method  "$g_Ret"  '*'  '\*'

  g_Ret="${String#*$g_Ret*}"
}


 
#//*********************************************************************
#// <<< [RightOfLastStr_func] >>> 
#//*********************************************************************
function  RightOfLastStr_func()
{
  local  String="$1"
  local  Key="$2"
  CheckArgCount_func  2 "$@"

  StringClass.replace_method  "$Key"    '\'  '\\'
  StringClass.replace_method  "$g_Ret"  '*'  '\*'

  g_Ret="${String##*$g_Ret}"
}


 
#//*********************************************************************
#// <<< [StringClass.indexOf_method] >>> 
#//*********************************************************************
function  StringClass.indexOf_method()
{
  local  self="$1"
  local  Keyword="$2"
  local  StartIndex="$3"
  CheckMinArgCount_func  2 "$@"
  CheckMaxArgCount_func  3 "$@"

  if [ "$StartIndex" == "" ];then  StartIndex=0  ;fi
  if [ "$StartIndex" -le "0" ];then  #// -le:"<="
    part="${self%%$Keyword*}"
    if [ "$part" == "$self" ];then
      g_Ret=-1
    else
      g_Ret=$(( ${#part} ))
    fi
  else
    self="${self:$StartIndex}"
    part="${self%%$Keyword*}"
    if [ "$part" == "$self" ];then
      g_Ret=-1
    else
      g_Ret=$(( ${#part} + $StartIndex ))
    fi
  fi
}


 
#//*********************************************************************
#// <<< [StringClass.lastIndexOf_method] >>> 
#//*********************************************************************
function  StringClass.lastIndexOf_method()
{
  local  self="$1"
  local  Keyword="$2"
  local  StartIndex="$3"
  CheckMinArgCount_func  2 "$@"
  CheckMaxArgCount_func  3 "$@"

  if [ "$StartIndex" == "" ];then  StartIndex=0  ;fi
  if [ "$StartIndex" -le "0" ];then  #// -le:"<="
    part="${self%$Keyword*}"
    if [ "$part" == "$self" ];then
      g_Ret=-1
    else
      g_Ret=$(( ${#part} ))
    fi
  else
    self="${self:0:$(( $StartIndex + ${#Keyword} ))}"
    part="${self%$Keyword*}"
    if [ "$part" == "$self" ];then
      g_Ret=-1
    else
      g_Ret=${#part}
    fi
  fi
}


 
#//*********************************************************************
#// <<< [StringClass.replace_method] >>> 
#//*********************************************************************
function  StringClass.replace_method()
{
  local  String="$1"
  local  From="$2"
  #// To="$3"

  StringEscapeUtilsClass.escapeBashReplace_method  "$From"
  g_Ret="${String//$g_Ret/$3}"
}


 
#//*********************************************************************
#// <<< [StringClass.toLowerCase_method] >>> 
#//*********************************************************************
function  StringClass.toLowerCase_method()
{
  #// for bash 4
  #// local  self="$1"
  #// echo  "${self,,}"

  #// for bash 3
  g_Ret=`echo  "$1" | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
}


 
#//*********************************************************************
#// <<< [StringClass.toUpperCase_method] >>> 
#//*********************************************************************
function  StringClass.toUpperCase_method()
{
  #// for bash 4
  #// local  self="$1"
  #// echo  "${self^^}"

  #// for bash 3
  g_Ret=`echo  "$1" | sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
}


 
#//*********************************************************************
#// <<< [StringEscapeUtilsClass.escapeGrep_method] >>> 
#//*********************************************************************
function  StringEscapeUtilsClass.escapeGrep_method()
{
  local  Str="$1"
    Str="${Str//\\/\\\\}"
    Str="${Str//-/\-}"
    Str="${Str//./\.}"
    Str="${Str//$/\\$}"
    Str="${Str//^/\^}"
    Str="${Str//{/\{}"
    Str="${Str//\}/\}}"
    Str="${Str//[/\[}"
    Str="${Str//]/\]}"
    Str="${Str//\*/\*}"
    Str="${Str//+/\+}"
  g_Ret="${Str//\?/\?}"
}


 
#//*********************************************************************
#// <<< [StringEscapeUtilsClass.escapeSed_method] >>> 
#//*********************************************************************
function  StringEscapeUtilsClass.escapeSed_method()
{
  local  Str="$1"
    Str="${Str//\\/\\\\}"
    Str="${Str//./\.}"
    Str="${Str//$/\\$}"
    Str="${Str//^/\^}"
    Str="${Str//[/\[}"
    Str="${Str//]/\]}"
    Str="${Str//\*/\*}"
    Str="${Str//\?/\?}"
  g_Ret="${Str//\//\/}"
}


 
#//*********************************************************************
#// <<< [StringEscapeUtilsClass.escapeBashReplace_method] >>> 
#//*********************************************************************
function  StringEscapeUtilsClass.escapeBashReplace_method()
{
  local  Str="$1"
    Str="${Str//\\/\\\\}"
    Str="${Str//\}/\}}"
    Str="${Str//\(/\\(}"
    Str="${Str//\)/\\)}"
    Str="${Str//\*/\\*}"
    Str="${Str//\?/\\?}"
  g_Ret="${Str//\//\\/}"
}


 
#//*********************************************************************
#// <<< [StringEscapeUtilsClass.escapeBashDoubleQuot_method] >>> 
#//*********************************************************************
function  StringEscapeUtilsClass.escapeBashDoubleQuot_method()
{
  local  Str="$1"
    Str="${Str//\\/\\\\}"
    Str="${Str//$/\\$}"
  g_Ret="${Str//\//\\/}"
}


 
#//*********************************************************************
#// <<< [StringEscapeUtilsClass.escapeBashParam_method] >>> 
#//*********************************************************************
function  StringEscapeUtilsClass.escapeBashParam_method()
{
  local  Str="$1"
    Str="${Str//\\/\\\\}"
    Str="${Str// /\\ }"
  g_Ret="${Str//$/\\$}"
}


 
#//*********************************************************************
#// <<< [ReplaceTextFile_func] >>> 
#//*********************************************************************
function  ReplaceTextFile_func()
{
  local  Path="$1"
  local  From="$2"
  local  To="$3"
  local  Opt="$4"

  CheckMinArgCount_func  2 "$@"
  CheckMaxArgCount_func  4 "$@"

  local  str1
  local  str2
  local  slash
  local  slashes=( "%" "/" )

  CheckWritable_func  "$Path"

  if [ "$Opt" == "-i" ];then  Opt="i"  ;fi

  sed_setIsAbleToNotCaseSensitive_func
  if [ "$g_sed_isAbleToNotCaseSensitive" == "0" ];then
    StringClass.indexOf_method  "$Opt"  "i"
    if [ "$g_Ret" -ge 0 ];then
      Error_func  "-i オプションは指定できません。"
    fi
  fi

  for  slash  in  ${slashes[@]};do

    LeftOfStr_func  "$From"  "$slash" ; str1="$g_Ret"
    LeftOfStr_func  "$To"    "$slash" ; str2="$g_Ret"
    if [ x"$str1" == x"$From"  -a  x"$str2" == x"$To" ];then  #// $From and $To do not have $slash.

      RightOfStr_func  "$From"  "\n" ; str1="$g_Ret"
      RightOfStr_func  "$To"    "\n" ; str2="$g_Ret"
      if [ x"$str1" == x"$From"  -a  x"$str2" == x"$To" ];then  #// $str1 and $str2 are single line,
        sed -i.bak -e "s$slash$From$slash$To${slash}g$Opt"  "$Path" ;  rm "$Path.bak"
      else
        RightOfStr_func  "$str1"  "\n" ; str2="$g_Ret"
        if [ "$str1" != "$str2" ];then
          Error_func  "置き換える前の文字列は３行以上にできません。"
        fi

        #// for GNU sed
        #// sed -i.bak -e '/\n/! {;$q;N;};'"s$slash$From$slash$To${slash}g$Opt;P;D;"  "$Path" ;  rm "$Path.bak"

        #// for BSD sed in Mac OS X Snow Leopard
        To=`echo "$To" | sed  -e 's/\\\\n/\\\\\\'"$LF"'/g' `
        cp  "$Path"  "$Path.bak"  #// mv では、chmod 属性が消えてしまいます
        sed -e '/\n/! {;$q;N;};'"s$slash$From$slash$To${slash}g$Opt;P;D;"  "$Path.bak" > $Path
        rm  "$Path.bak"
      fi
      return
    fi
  done ; done_func $?

  Error_func  "ReplaceTextFile_func は、置き換える前後の文字列に / と % の両方を含むことはできません"
}


 
#//*********************************************************************
#// <<< [sed_setIsAbleToNotCaseSensitive_func] >>> 
#//*********************************************************************
g_sed_isAbleToNotCaseSensitive=""
function  sed_setIsAbleToNotCaseSensitive_func()
{
  if [ "$g_sed_isAbleToNotCaseSensitive" == "" ];then
    local  status=0
    echo -n "" | sed -e s/a/b/i > /dev/null  2>&1  || status=$?
    g_sed_isAbleToNotCaseSensitive=$(( 1 - $status ))
  fi
}


 
#//*********************************************************************
#// <<< [ReplaceTextFileLineRange_func] >>> 
#//*********************************************************************
function  ReplaceTextFileLineRange_func()
{
  local  Path="$1"
  local  From="$2"
  local  FromEnd="$3"
  local  To="$4"
  local  Opt="$5"
  local  str
  local  a1

  CheckMinArgCount_func  3 "$@"
  CheckMaxArgCount_func  5 "$@"

  CheckWritable_func  "$Path"

  if [ "$Opt" == "-i" ];then  Opt="i"  ;fi

  sed_setIsAbleToNotCaseSensitive_func
  if [ "$g_sed_isAbleToNotCaseSensitive" == "0" ];then
    StringClass.indexOf_method  "$Opt"  "i"
    if [ "$g_Ret" -ge 0 ];then
      Error_func  "i オプションは指定できません。"
    fi
  fi

  LeftOfStr_func  "$From"  "%"
  if [ "$g_Ret" != "$From" ];then  Error_func  ;fi

  LeftOfStr_func  "$FromEnd"  "%"
  if [ "$g_Ret" != "$FromEnd" ];then  Error_func  ;fi

  Opt=`StringClass.toUpperCase_method  "$Opt"`

  if [ "$To" != "" ];then
    #// for GNU sed
    #// To="c${To//\\n/\\${LF}}"

    #// for BSD sed in Mac OS X Snow Leopard
    if [ "$To" == "\n" ];then
      a1=`echo  $'a\nb\nc' | sed -e '/b/c\'"${LF}" `
      if [ "$a1" == "a${LF}${LF}c" ];then
        To=""
      fi
    fi

    To="c\\${LF}${To//\\n/\\${LF}}"
  else
    To="d"
  fi

  #// for GNU sed
  #// if [ "$FromEnd" == "" ];then
  #//   sed -i.bak -e '\%'"$From"'%'"$Opt$To"  "$Path" ;  rm "$Path.bak"
  #// else
  #//   sed -i.bak -e '\%'"$From"'%'"$Opt"',\%'"$FromEnd"'%'"$Opt$To"  "$Path" ;  rm "$Path.bak"
  #// fi

  #// for BSD sed in Mac OS X Snow Leopard
  cp  "$Path"  "$Path.bak"  #// mv では、chmod 属性が消えてしまいます
  if [ "$FromEnd" == "" ];then
    sed -e '\%'"$From"'%'"$Opt$To"  "$Path.bak" > $Path
  else
    sed -e '\%'"$From"'%'"$Opt"',\%'"$FromEnd"'%'"$Opt$To"  "$Path.bak" > $Path
  fi
  rm  "$Path.bak"
}


 
#//*********************************************************************
#// <<< [MultiLine_func] >>> 
#//*********************************************************************
function  MultiLine_func()
{
  local  LineFeedChar="$1"
  shift  1

  local  Params=( "$@" )
  local  line
  local  lfs

  g_Ret=""
  for line  in "$@" ;do
    if [ "$line" == "" ];then
      lfs="$lfs$LineFeedChar"
    else
      g_Ret="$g_Ret$lfs$line"
      lfs="$LineFeedChar"
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [ArrayClass.getLength_method] >>>
#//*********************************************************************
function  ArrayClass.getLength_method()
{
  local  self="$1"

  eval  g_Ret='${#'"$self"'[@]}'
}


 
#//*********************************************************************
#// <<< [ArrayClass.get_method] >>>
#//*********************************************************************
function  ArrayClass.get_method()
{
  local  self="$1"
  local  Index="$2"
  local  over_index
  CheckArgCount_func  2 "$@"

  eval  over_index='${#'"$self"'[@]}'
  if [ "$Index" -ge "$over_index"  -o  "$Index" -lt "0" ];then
    Error_func  "<ERROR msg=\"インデックスが範囲外です\" index=\"$Index\"/>"
  fi

  eval  g_Ret='"${'"$self"'[$Index]}"'
}


 
#//*********************************************************************
#// <<< [ArrayClass.set_method] >>>
#//*********************************************************************
function  ArrayClass.set_method()
{
  local  self="$1"
  local  Index="$2"
  local  Value="$3"
  local  over_index
  local  num
  CheckArgCount_func  3 "$@"

  eval  over_index='${#'"$self"'[@]}'
  if [ "$Index" -lt "0" ];then
    Error_func  "<ERROR msg=\"インデックスが範囲外です\" index=\"$Index\"/>"
  fi

  for (( num = over_index;  $num < $Index;  num++ )) ;do
    eval  "$self"'[$num]=""'
  done ; done_func $?

  eval  "$self"'[$Index]='"'$Value'"
}


 
#//*********************************************************************
#// <<< [ArrayClass.remove_method] >>>
#//*********************************************************************
function  ArrayClass.remove_method()
{
  local  self="$1"
  local  Index="$2"
  local  num
  local  over_index
  local  last_index
  CheckArgCount_func  2 "$@"

  eval  over_index='${#'"$self"'[@]}'
  if [ "$Index" -ge "$over_index"  -o  "$Index" -lt "0" ];then
    Error_func  "<ERROR msg=\"インデックスが範囲外です\" index=\"$Index\"/>"
  fi

  last_index=$(( $over_index - 1 ))
  for (( num = $Index;  $num < $last_index;  num++ )) ;do
    eval  "$self"'[$num]="${'"$self"'[$(( $num + 1 ))]}"'
  done ; done_func $?

  eval  unset "$self"'[$last_index]'
}


 
#//*********************************************************************
#// <<< [ArrayClass.clear_method] >>> 
#//*********************************************************************
function  ArrayClass.clear_method()
{
  local  self="$1"

  unset $self
  unset $self  #// 配列をクリアするには２回必要？
}


 
#//*********************************************************************
#// <<< [ArrayClass.fromLines_method] >>> 
#//*********************************************************************
function  ArrayClass.fromLines_method()
{
  local  out_Array="$1"
  local  Lines="$2"
  local  line
  local  i
  local  keys

  CheckOutParamIsConflictToLocal_func  $out_Array  out_Array  Lines  line  i  keys

  unset  $out_Array
  unset  $out_Array  #// 配列をクリアするには２回必要？

  i=0
  while true; do
    line="${Lines%%$LF*}"
    if [ "$line" != "" ];then  eval $out_Array[$i]="'$line'"  ;fi
    if [ "$line" == "$Lines" ];then  break  ;fi
    i=$(( $i + 1 ))
    Lines=${Lines:$(( ${#line} + 1 ))}  #// next line
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [ArrayClass.fromCSV_method] >>> 
#//*********************************************************************
function  ArrayClass.fromCSV_method()
{
  local  out_Array="$1"
  local  CSV__="$2"
  local  index__=0
  local  item__
  local  char__
  local  next__
  CheckArgCount_func  2 "$@"

  CheckOutParamIsConflictToLocal_func  "$out_Array" \
    CSV__  out_Array  index__  item__  __field  char__  next__

  unset  $out_Array
  unset  $out_Array  #// 配列をクリアするには２回必要？

  while true; do
    item__=( $CSV__ )  #// ${item__[0]} does not have space
    StringClass.substring_method  ${item__[0]}  0  1 ; char__="$g_Ret"
    if [ "$char__" == "\"" ];then
      RightOfStr_func  "$CSV__"  "\"" ; CSV__="$g_Ret"
      LeftOfStr_func  "$CSV__"  "\"" ; item__="$g_Ret"
      RightOfStr_func  "$CSV__"  "\"" ; CSV__="$g_Ret"
    elif [ "$char__" == "" ];then
      break
    else
      LeftOfStr_func  "$CSV__"  "," ; item__="$g_Ret"
      StringClass.trim_method  "$item__" ; item__="$g_Ret"
    fi
    RightOfStr_func  "$CSV__"  "," ; next__="$g_Ret"

    SetArrItem_func  $out_Array  $index__  "$item__"
    index__=$(( $index__ + 1 ))

    if [ x"$next__" == x""  -o  x"$next__" == x"$CSV__" ];then  break  ;fi
    CSV__="$next__"
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [IsSameArrayOutOfOrder_func] >>>
#//*********************************************************************
function  IsSameArrayOutOfOrder_func()
{
  local  ArrayACount="$1"
  local  ArrayAB=("$@")

  local  a_index
  local  b_index
  local  is_same_arr

  IsNumeric_func  "$ArrayACount" ; if [ "$g_Ret" == "0" ];then  Error_func  ;fi

  if [ ${#ArrayAB[@]} != $(( $ArrayACount * 2 + 1 )) ];then  g_Ret="0" ; return ;fi

  for (( b_index = $ArrayACount + 1;  b_index < ${#ArrayAB[@]};  b_index ++ )) ;do
    for (( a_index = 1;  a_index <= $ArrayACount;  a_index ++ )) ;do
      if [ "${ArrayAB[$a_index]}" == "${ArrayAB[$b_index]}" ];then
        if [ "${is_same_arr[$a_index]}" == "" ];then
          is_same_arr[$a_index]=1
          break
        fi
      fi
    done ; done_func $?
  done ; done_func $?

  for (( a_index=1;  a_index <= $ArrayACount;  a_index ++ )) ;do
    if [ "${is_same_arr[$a_index]}" == "" ];then
      g_Ret="0" ; return
    fi
  done ; done_func $?
  g_Ret="1"
}


 
#//*********************************************************************
#// <<< [Extract_func] >>> 
#//*********************************************************************
function  Extract_func()
{
  local  PackagePath="$1"
  local  DstFolder="$2"
  local  Option1="$3"

  local  ext1
  local  ext2
  local  i
  local  extract_folder
  local  status
  local  trans_option_1
  local  trans_option_2
  local  dst_name
  local  arguments
  $declare_AssociativeArrayClass  option

  echo  "$PackagePath -> $DstFolder  $Option1"

  CheckWritable_func  "$DstFolder"
  dst_name=`basename "$DstFolder"`

  RightOfLastStr_func  "$PackagePath"  "." ; ext2="$g_Ret"
  LeftOfLastStr_func   "$PackagePath"  "."
  RightOfLastStr_func  "$g_Ret"  "." ; ext1="$g_Ret"

  #// --transform option
  GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option
  Attr_func  option  "transform_from" ; trans_option_1="$g_Ret"


  if [ "$trans_option_1" == "" ];then

    #// set one_folder_path
    ListUpIn_func  "$PackagePath" > /tmp/_Extract_func.txt  #// tar write error, if pipe was used
    one_folder_path=`head -n 1 /tmp/_Extract_func.txt`

    StringClass.substring_method  "$one_folder_path"  0  1
    if [ "$g_Ret" == "/" ];then
      one_folder_path=""
    else
      StringClass.substring_method  "$one_folder_path"  0  2
      if [ "$g_Ret" == "./" ];then
        StringClass.indexOf_method  "$one_folder_path"  "/"  2
      else
        StringClass.indexOf_method  "$one_folder_path"  "/"
      fi
      if [ "$g_Ret" == "-1" ];then
        one_folder_path=""
      else
        StringClass.substring_method  "$one_folder_path"  0  $g_Ret ; one_folder_path="$g_Ret"
      fi
    fi


    #// set one_folder_path="", if there was two folders
    if [ "$one_folder_path" != "" ];then
      status=0
      cat /tmp/_Extract_func.txt | grep -v "^$one_folder_path/" || status=$?
      CheckPipeStatus_func  "${PIPESTATUS[@]}"
      if [ "$status" == "0" ];then  #// found out of one_folder_path
        one_folder_path=""
      fi
    fi
    rm  /tmp/_Extract_func.txt


    #// set trans_option
    if [ "$one_folder_path" != "" ];then
      if [ "$ext2" == "zip" ];then
        trans_option_1="$one_folder_path"
      else
        GetExtractTransformOptionName_func  "$DstFolder"
        if [ "$g_Ret" == "--transform" ];then
          trans_option_1="--transform=s%^$one_folder_path%$dst_name%"
        else
          trans_option_1="-s"
          trans_option_2="%^$one_folder_path/%$dst_name/%"
        fi
      fi
    fi


    #// set extract_folder
    if [ "$one_folder_path" == "" ];then
      extract_folder="$DstFolder"
    else
      GetParentAbsPath_func  "$DstFolder" ; extract_folder="$g_Ret"
    fi

  else

    #// modify trans_option
    StringClass.right_method  "$trans_option_1"  1
    if [ "$g_Ret" == "/" ];then
      StringClass.length_method  "$trans_option_1"
      StringClass.substring_method  "$trans_option_1"  0  $(( $g_Ret - 1 ))
      trans_option_1="$g_Ret"
    fi
    dst_name=`basename  "$DstFolder"`

    if [ "$ext2" != "zip" ];then
      GetExtractTransformOptionName_func  "$DstFolder"
      if [ "$g_Ret" == "--transform" ];then
        trans_option_1="--transform=s%^$trans_option_1%$dst_name%"
      else
        trans_option_2="%^$trans_option_1%$dst_name%"
        trans_option_1="-s"
      fi
    fi
    extract_folder=`dirname  "$DstFolder"`
  fi


  #// extract
  if [ x"$ext1" != x"tar"  -a  x"$ext2" == x"gz" ];then
    ExtractGZ_func  "$PackagePath"  "$extract_folder"
  elif [ "$ext2" == "zip" ];then
    ExtractZip_func  "$PackagePath"  "$DstFolder"  "$trans_option_1"
  else
    if [ ! -e "$extract_folder" ];then  mkdir -p  "$extract_folder"  ;fi
    if [ "$trans_option_1" == "" ];then
      echo  "tar xvf  \"$PackagePath\" -C \"$extract_folder\""
      tar xvf  "$PackagePath" -C "$extract_folder"
    else
      echo  "tar xvf  \"$PackagePath\" -C \"$extract_folder\"  \"$trans_option_1\"  \"$trans_option_2\""
      tar xvf  "$PackagePath" -C "$extract_folder"  "$trans_option_1"  "$trans_option_2"
    fi
  fi

  AssociativeArrayClass.destroy_method  option
}


declare  g_ExtractTransformOptionName  #// "-s" or "--transform"

function  GetExtractTransformOptionName_func()
{
  if [ "$g_ExtractTransformOptionName" == "" ];then

    local  WorkDstFolder="$1"
    local  is_pushd
    local  status
    local  i
    local  a1

    for (( i = 1; i < 100; i ++ ));do
      if [ "$i" == "99" ];then  Error_func  "$WorkDstFolder にフォルダーが作れません"  ;fi
      a1="$WorkDstFolder/_extract_trans_test_$i"
      if [ ! -e "$a1" ];then
        WorkDstFolder="$a1"
        break
      fi
    done ; done_func $?

    while TryStart_func; do

      mkdir -p  "$WorkDstFolder"
      pushd  "$WorkDstFolder" > /dev/null
      is_pushd=1

      echo  "a" > a.txt
      tar cvjf  "a.tar.bz2"  "a.txt" > /dev/null

      status=0
      tar xvf  "a.tar.bz2"  --transform="s%a.txt%b.txt%" > /dev/null 2>&1 || status=$?

      if [ "$status" == "0"  -a  -e "b.txt" ];then
        g_ExtractTransformOptionName="--transform"
      else
        status=0
        tar xvf  "a.tar.bz2"  -s "%a.txt%b.txt%" > /dev/null 2>&1 || status=$?

        if [ "$status" == "0"  -a  -e "b.txt" ];then
          g_ExtractTransformOptionName="-s"
        else
          Error_func
        fi
      fi

    TryEnd1_func; done ;TryEnd2_func $?
      #// Finally
      if [ "$is_pushd" == "1" ];then  popd > /dev/null ;fi
      rm_func  "$WorkDstFolder"
    if [ "$g_ExitStatus" != "0" ]; then  ErrClass.raiseOverwrite_method  ;fi
  fi
  g_Ret="$g_ExtractTransformOptionName"
}


 
#//*********************************************************************
#// <<< [ExtractGZ_func] >>> 
#//*********************************************************************
function  ExtractGZ_func()
{
  local  GzPath="$1"
  local  ExtractedPath="$2"
  CheckArgCount_func  2 "$@"

  if [ "$TMPDIR" == "" ]; then  temp_folder="$HOME"  ;else  temp_folder="$TMPDIR"  ;fi

  if [ "$GzPath" == "${ExtractedPath}.gz" ]; then
    if [ -e "$temp_folder/_ExtractGZ_func.gz" -o -e "$temp_folder/_ExtractGZ_func" ]; then
      unset ERROR;${ERROR:?exist _ExtractGZ_func.gz is for temporary}  ;fi

    cp -ap  "$GzPath"  "$temp_folder/_ExtractGZ_func.gz"
    echo  "gunzip  \"$temp_folder/_ExtractGZ_func.gz\""
    gunzip  "$temp_folder/_ExtractGZ_func.gz"
    mv  "$temp_folder/_ExtractGZ_func"  "$ExtractedPath"
  else
    cp -ap  "$GzPath"  "${ExtractedPath}.gz"
    rm_func "$ExtractedPath"
    echo  "gunzip  \"${ExtractedPath}.gz\""
    gunzip  "${ExtractedPath}.gz"
  fi
}


 
#//*********************************************************************
#// <<< [ExtractZip_func] >>> 
#//*********************************************************************
function  ExtractZip_func()
{
  local  PackagePath="$1"
  local  DstFolder="$2"
  local  TarnsformFrom="$3"
  local  dst_name ; dst_name=`basename "$DstFolder"`
  local  from_name ; from_name=`basename "$TarnsformFrom"`

  if [ "$DstFolder" == "" ];then  DstFolder="$PWD" ;fi

  if [ x"$TarnsformFrom" == x"" ];then
    mkdir_func  "$DstFolder"
    echo  "unzip -o -d  \"$DstFolder\"  \"$PackagePath\""
    unzip -o -d "$DstFolder"  "$PackagePath"
  elif [ x"$dst_name" == x"$from_name" ];then
    GetParentAbsPath_func  "$DstFolder"
    DstFolder="$g_Ret"
    mkdir_func  "$DstFolder"
    echo  "unzip -o -d  \"$DstFolder\"  \"$PackagePath\""
    unzip -o -d "$DstFolder"  "$PackagePath"
  else
    local  tmp_folder
    local  link_path
    local  num

    tmp_folder="$DstFolder/_extracting_"
    for (( num = 1;  ;  num ++ )) ;do
      if [ "$num" == 1000 ];then  Error_func  ;fi
      if [ ! -e "$tmp_folder$num" ];then  break  ;fi
    done ; done_func $?
    tmp_folder="$tmp_folder$num"
    mkdir -p  "$tmp_folder"

    link_path="$tmp_folder/$from_name"
    StringClass.substring_method  "$DstFolder"  0  1
    if [ "$g_Ret" == "/" ];then
      ln -s "$DstFolder"  "$link_path"
    else
      ln -s ".."  "$link_path"
    fi

    echo  "unzip -o -d  \"$tmp_folder\"  \"$PackagePath\""
    unzip -o -d "$tmp_folder"  "$PackagePath"

    rm  "$link_path"
    rmdir  "$tmp_folder"
  fi
}


 
#//*********************************************************************
#// <<< [ListUpIn_func] >>> 
#//*********************************************************************
function  ListUpIn_func()
{
  local  PackagePath="$1"

  local  ext1
  local  ext2
  local  name

  RightOfLastStr_func  "$PackagePath"  "." ; ext2="$g_Ret"
  LeftOfLastStr_func   "$PackagePath"  "."
  RightOfLastStr_func  "$g_Ret"  "." ; ext1="$g_Ret"

  if [ x"$ext1" == x"tar"  -a  x"$ext2" == x"bz2" ];then
    bzip2 -dkc "$PackagePath" | tar t
  elif [ x"$ext1" == x"tar"  -a  x"$ext2" == x"gz" ];then
    tar tfz  "$PackagePath"
  elif [ x"$ext1" != x"tar"  -a  x"$ext2" == x"gz" ];then
    LeftOfLastStr_func  "$PackagePath"  "." ; name="$g_Ret"
    echo  "$name"
  elif [ "$ext2" == "zip" ];then
    unzip -l "$PackagePath" | sed -e "1,3d" -e '/^ *---/,$d' -e "s/.*:[0-9]* *//"
    CheckPipeStatus_func  "${PIPESTATUS[@]}"
  else
    Error_func  ".$ext.$ext2 形式は、サポートしていません。"
  fi
}


 
#//*********************************************************************
#// <<< [ExpandWildcard_func] >>>
#//*********************************************************************
function  ExpandWildcard_func()
{
  local  out_FolderAbsPath="$2"
  local  out_StepPaths="$3"
  local  list__
  local  last__
  local  physical_folder__

  CheckMinArgCount_func  3 "$@"

  local  locals="out_FolderAbsPath  out_StepPaths  list__  last__  physical_folder__  locals"
  CheckOutParamIsConflictToLocal_func  $out_FolderAbsPath  $locals
  CheckOutParamIsConflictToLocal_func  $out_StepPaths      $locals

  #//=== call ExpandWildcardSub_func
  list__=`ExpandWildcardSub_func  "$@" `
  ArrayClass.fromLines_method  $out_StepPaths  "$list__"  #//[out] $out_StepPaths

  #//=== get physical_folder__
  ArrayClass.getLength_method  $out_StepPaths
  last__=$(( $g_Ret - 1 ))
  ArrayClass.get_method  $out_StepPaths  $last__ ; physical_folder__="$g_Ret"

  StringClass.length_method  "$physical_folder__" ; length="$g_Ret"
  length=$(( $length + 1 ))

  ArrayClass.remove_method  $out_StepPaths  $last__

  #//=== get $out_FolderAbsPath
  last__=$(( $last__ - 1 ))
  ArrayClass.get_method  $out_StepPaths  $last__
  SetOutput_func  $out_FolderAbsPath  "$g_Ret"
  ArrayClass.remove_method  $out_StepPaths  $last__

  #//=== change to step_path
  for (( last__ = $last__ - 1 ;  $last__ >= 0 ; last__ -- )) ;do
    ArrayClass.get_method  $out_StepPaths  $last__
    StringClass.substring_method  "$g_Ret"  $length
    if [ "$g_Ret" == "" ];then  g_Ret="."  ;fi
    ArrayClass.set_method  $out_StepPaths  $last__  "$g_Ret"
  done ; done_func $?
}


function  ExpandWildcardSub_func()
{
  local  WildcardPath="$1"
  local  arguments
  $declare_AssociativeArrayClass  option
  local  a1
  local  folder
  local  physical_folder
  local  options
  local  file_name
  local  all_type

  local  locals="WildcardPath  arguments  option  a1  folder  physical_folder  options  file_name  all_type  locals"
  CheckOutParamIsConflictToLocal_func  $WildcardPath  $locals

  GetLongOptions_func  arguments  option  "$@"  #//[out] arguments, option

  unset  $out_StepPaths
  unset  $out_StepPaths  #// 配列をクリアするには２回必要？

  a1=`dirname  "$WildcardPath"`
  if [ "$a1" == "" ];then  a1="."  ;fi
  GetAbsPath_func  "$a1" ; folder="$g_Ret"
  readlink_func  "$folder" ; physical_folder="$g_Ret"

  file_name=`basename  "$WildcardPath"`

  Attr_func  option  "SubFolder"
  if [ "$g_Ret" == "" ];then
    options="${options} -maxdepth 1"
  fi

  all_type="1"

  Attr_func  option  "Folder"
  if [ "$g_Ret" == "1" ];then
    find  "$physical_folder" $options -name "$file_name" -type d -print
    all_type=""
  fi

  Attr_func  option  "File"
  if [ "$g_Ret" == "1" ];then
    find  "$physical_folder" $options -name "$file_name" -type f -print
    all_type=""
  fi

  Attr_func  option  "Link"
  if [ "$g_Ret" == "1" ];then
    find  "$physical_folder" $options -name "$file_name" -type l -print
    all_type=""
  fi

  if [ "$all_type" == "1" ];then
    find  "$physical_folder" $options -name "$file_name" -print
  fi

  AssociativeArrayClass.destroy_method  option
  echo  "$folder"
  echo  "$physical_folder"
}


 
#//*********************************************************************
#// <<< [rm_func] >>> 
#//*********************************************************************
function  rm_func()
{
  local  Paths=( "$@" )
  local  path

  for path  in "${Paths[@]}" ;do
    if [ "$path" != "" ];then
      CheckWritable_func  "$path"

      if [ -d "$path" ]; then
        $g_TemporarySudo  chmod -R a+rw  "$path"
        $g_TemporarySudo  rm -rf  "$path"
      elif [ -f "$path" ]; then
        $g_TemporarySudo  chmod a+rw  "$path"
        $g_TemporarySudo  rm -f  "$path"
      elif [ -e "$path"  -o  -L "$path" ]; then
        $g_TemporarySudo  rm -f  "$path"
      fi
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [mkdir_func] >>> 
#//*********************************************************************
function  mkdir_func()
{
  local  Path="$1"
  CheckArgCount_func  1 "$@"

  CheckWritable_func  "$Path"

  if [ ! -d "$Path" ];then
    $g_TemporarySudo  mkdir -p "$Path"
  fi
}


 
#//*********************************************************************
#// <<< [chmod_x_func] >>> 
#//*********************************************************************
function  chmod_x_func()
{
  local  FolderPath="$1"
  local  SetPaths="$2"
  local  UnsetPaths="$3"
  local  wildcard
  local  wildcards
  local  folder
  local  step_paths
  local  path

  ArrayClass.fromCSV_method  wildcards  "$SetPaths"  #//[out] wildcards
  for wildcard  in "${wildcards[@]}" ;do
    if [ "$wildcard" != "." ];then
      ExpandWildcard_func  "$work_folder/$wildcard"  folder  step_paths  --File  --SubFolder  #//[out]folder, step_paths
      for path  in "${step_paths[@]}" ;do
        echo  "chmod +x  \"$folder/$path\""
        chmod +x  "$folder/$path"
      done ; done_func $?
    fi
  done ; done_func $?

  ArrayClass.fromCSV_method  wildcards  "$UnsetPaths"  #//[out] wildcards
  for wildcard  in "${wildcards[@]}" ;do
    if [ "$wildcard" != "." ];then
      ExpandWildcard_func  "$work_folder/$wildcard"  folder  step_paths  --File  --SubFolder  #//[out]folder, step_paths
      for path  in "${step_paths[@]}" ;do
        echo  "chmod -x  \"$folder/$path\""
        chmod -x  "$folder/$path"
      done ; done_func $?
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [MakeSymbolicLink_func] >>> 
#//*********************************************************************
function  MakeSymbolicLink_func()
{
  local  LinkSrcPath="$1"
  local  Target="$2"
  CheckArgCount_func  2 "$@"

  CheckWritable_func  "$LinkSrcPath"

  if [ -d "$LinkSrcPath" ];then
    if [ -L "$LinkSrcPath" ];then
      rm  "$LinkSrcPath"
      $g_TemporarySudo  ln -s  "$Target"  "$LinkSrcPath"
    else
      Error_func  "フォルダーが存在します"
    fi
  else
    $g_TemporarySudo  ln -sf  "$Target"  "$LinkSrcPath"
  fi
}


 
#//*********************************************************************
#// <<< [chown_it_and_parent_func] >>> 
#//*********************************************************************
function  chown_it_and_parent_func()
{
  local  Option=""
  local  Owner="$1"
  if [ "$Owner" == "-R" ];then
    Option="$Owner"
    shift
    Owner="$1"
  fi
  local  Path="$2"
  local  parent

  CheckWritable_func  "$Path"

  GetParentAbsPath_func  "$Path" ; parent="$g_Ret"

  if [ -e "$Path" ];then
    $g_TemporarySudo  chown  $Option  "$Owner"  "$Path"
  fi

  if [ ! -d "$parent" ];then
    $g_TemporarySudo  mkdir -p  "$parent"
  fi
  $g_TemporarySudo  chown  $Option  "$Owner"  "$parent"
}


 
#//*********************************************************************
#// <<< [AppKeyClass.newWritable_method] >>> 
#//*********************************************************************
function  AppKeyClass.newWritable_method()
{
  local  AppKey="$1"
  shift  1
  local  Args=( "$@" )
  local  index
  local  count

  if [ "$AppKey" != "AppKey4293" ]; then  Error_func  "AppKeyClass.newWritable_method needs \$2 of Main_func"  ;fi

  unset g_WritableFolders8920
  unset g_WritableFolders8920  #// 配列をクリアするには２回必要？

  count=0
  for (( index = 0; index < ${#Args[@]}; index ++ ));do
    if [ "${Args[$index]}" != "" ];then
      GetAbsPath_func  "${Args[$index]}"
      g_WritableFolders8920[$count]="$g_Ret"
      count=$(( $count + 1 ))
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [CheckWritable_func] >>> 
#//*********************************************************************
function  CheckWritable_func()
{
  local  Path="$1"
  CheckArgCount_func  1 "$@"

  local  is_break=""
  local  writable

  GetAbsPath_func  "$Path"  "$PWD" ; Path="$g_Ret"

  if [ "$g_WritableFolders8920" == "" ]; then \
    Error_func  "<ERROR msg=\"Not call AppKeyClass.newWritable_method\" Path=\"$Path\"/>"  ;fi
  for  writable  in  ${g_WritableFolders8920[@]};do
    if [ "${Path%%$writable*}" == "" ]; then  is_break=1 ; break  ;fi
  done ; done_func $?
  if [ ! "$is_break" == "1" ]; then
    Error_func  "<ERROR msg=\"AppKeyClass.newWritable_method による書き込み許可がされていません。\"" \
       "Path=\"$Path\" Writable=\"$g_WritableFolders8920\"/>"
  fi
}


 
#//*********************************************************************
#// <<< [EchoTestStart_func] >>> 
#//*********************************************************************
function  EchoTestStart_func()
{
  local  args=("$@")
  if [ "${#args[@]}" == "0" ];then
    echo  ""
    echo  "((( ${FUNCNAME[1]} )))"
  else
    echo  ""
    echo  "((( $@ )))"
  fi
}


 
#//*********************************************************************
#// <<< [debugger] >>> 
#//*********************************************************************
function  de()
{
  debugger
}

function  debugger()
{
  g_DebugTrapFunc="StepRunning_func"

  trap 'DebugTrap_func  "$LINENO"  "$BASH_COMMAND"  "${PIPESTATUS[@]}"
    #// resume ${PIPESTATUS[@]}
    case "${#g_PipeStatus[@]}" in
      "2")
        return ${g_PipeStatus[0]} | true;;
      "3")
        return ${g_PipeStatus[0]} | return ${g_PipeStatus[1]} | true;;
    esac' DEBUG
}

function  StepRunning_func()
{
  local  LineNo__="$1"
  local  Command__="$2"
  shift  2
  g_PipeStatus=( "$@" )

  local  key__
  local  a1__

  if [ "$step_running_guided" == "" ]; then
    ErrClass.getCallTree_method  "$LINENO"  2  1
    echo  "$g_Ret"  >&2
    echo  "--- デバッガ情報 -------------------------"  >&2
    echo  "ステップ実行 … Enter キーを押してください"  >&2
    echo  "変数の値を表示 … 変数名を入力"              >&2
    echo  "------------------------------------------"  >&2
  fi

  echo  "${FUNCNAME[2]}() ${BASH_SOURCE[2]}:${BASH_LINENO[1]}"  >&2
  key__="goto_in_while"
  while [ "$key__" != "" ]; do
    read -p "$LineNo__: $Command__ " key__  #// break at the line

    #// inspect variable's value
    if [ "$key__" != "" ]; then

      case "$key__" in
       "LineNo__" | "Command__" | "key__" | "a1__" )
        echo  "変数 $key__ の値の表示はサポートしていません。";;

       *)
        CheckOutParamIsConflictToLocal_func  key__  

        key__=${key__/$/}  #// cut first $, if exists
        es  $key__  #// call es function
        ;;
      esac
    fi
  done ; done_func $?

  step_running_guided=1
}


 
#//*********************************************************************
#// <<< [ec] >>> 
#//*********************************************************************
function  ec()
{
  local  ExpressionArray__=("$@")
  local  Expression__="$@"
  local  evaled__

  echo  "ec> ${FUNCNAME[1]}() ${BASH_SOURCE[1]}(${BASH_LINENO[0]})"  >&2
  if [ "${#ExpressionArray__[@]}" != "0" ];then

    CheckEvalParamIsConflictToLocal_func  "$Expression__"  ExpressionArray__  Expression__  evaled__

    evaled__=`eval echo "\"""$Expression__""\""`
    if [ "$Expression__" == "$evaled__" ];then
      echo  "ec> \"$Expression__\""  >&2
    else
      echo  "ec> \"$Expression__\" == '""$evaled__""'" >&2
    fi
  fi
}


 
#//*********************************************************************
#// <<< [es] >>> 
#//*********************************************************************
function  es()
{
  local  Name__="$1"
  local  keys__
  local  value__
  local  index__
  local  is__

  if [ "$g_ExitStatus" == "0" ];then
    CheckArgCount_func  1 "$@"

    CheckOutParamIsConflictToLocal_func  "$Name__"  Name__  keys__  value__  index__
  fi

  eval  keys__=( '"${!'"$Name__"'[@]}"' )

  is__=0
  if [ x"$keys__" == x""  -o  x"$keys__" == x"0" ];then  is__=1 ;fi

  if [ "${#keys__[@]}" -le "1"  -a  "$is__" == "1" ];then
    eval  value__='"${'"$Name__"'}"'
    StringClass.indexOf_method  "$Name__"  "["
    if [ "$g_Ret" -ge "0" ];then
      echo -n 'Dump "${'"$Name__"}'" == '  >&2
    else
      echo -n 'Dump "$'"$Name__"'" == '  >&2
    fi
    echo  "'""$value__""'"  >&2
    if [ "$value__" == "" ];then
      echo  "00000000                                                    ||" >&2
      echo  "00000000" >&2
    else
      echo -n "$value__" | hexdump -C  >&2
    fi
    #// hexdump -C <<< "$value__"  >&2
  else
    for index__  in "${keys__[@]}" ;do
      es $Name__[$index__]
    done ; done_func $?
  fi
}


 
#//*********************************************************************
#// <<< [Error_func] >>> 
#//*********************************************************************
function  Error_func()
{
  ErrClass.getErrStr_method  "$@" ; g_Err_Desc="$g_Ret"
  return_func  1
}


 
#//*********************************************************************
#// <<< [return_func] >>> 
#//*********************************************************************
function  return_func()
{
  if [ "$g_Err_LineNo" == "???" ];then  g_Err_LineNo=${BASH_LINENO[0]}  ;fi
  return  "$1"
}


 
#//*********************************************************************
#// <<< [CheckPipeStatus_func] >>> 
#//*********************************************************************
function  CheckPipeStatus_func()
{
  local  pipe_status="$@"
  local  state

  for state in ${pipe_status[@]};do
    if [ "$state" != "0" ]; then
      echo  '${PIPESTATUS[@]} = '"${pipe_status[@]}" >&2
      g_Err_LineNo=${BASH_LINENO[0]}
      return  "$state"
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [CheckArgCount_func] >>> 
#//*********************************************************************
function  CheckArgCount_func()
{
  local  RequestArgumentCount="$1"
  shift  1
  local  Arguments=( "$@" )
  local  str

  if [ "${#Arguments[@]}" -ne "$RequestArgumentCount" ];then
    str="パラメーターの数が合っていません。 指定=${#Arguments[@]}, 要求=$RequestArgumentCount,"
    str="$str コマンドライン: ${FUNCNAME[1]} ${Arguments[@]}"
    Error_func  "$str"
  fi
}


 
#//*********************************************************************
#// <<< [CheckMinArgCount_func] >>> 
#//*********************************************************************
function  CheckMinArgCount_func()
{
  local  RequestArgumentCount="$1"
  shift  1
  local  Arguments=( "$@" )
  if [ "${#Arguments[@]}" -lt "$RequestArgumentCount" ];then
    echo  "パラメーターが少なすぎます。 指定=${#Arguments[@]}, 要求=$RequestArgumentCount"  >&2
    echo  "コマンドライン: ${FUNCNAME[1]} ${Arguments[@]}"  >&2
    Error_func
  fi
}


 
#//*********************************************************************
#// <<< [CheckMaxArgCount_func] >>> 
#//*********************************************************************
function  CheckMaxArgCount_func()
{
  local  RequestArgumentCount="$1"
  shift  1
  local  Arguments=( "$@" )
  if [ "${#Arguments[@]}" -gt "$RequestArgumentCount" ];then
    echo  "パラメーターが多すぎます。 指定=${#Arguments[@]}, 要求=$RequestArgumentCount"  >&2
    echo  "コマンドライン: ${FUNCNAME[1]} ${Arguments[@]}"  >&2
    Error_func
  fi
}


 
#//*********************************************************************
#// <<< [CheckOutParamIsConflictToLocal_func] >>> 
#//*********************************************************************
function  CheckOutParamIsConflictToLocal_func()
{
  local  OutParamName__="$1"
  shift  1
  local  LocalNames__=( "$@" )
  local  name__
  local  a1__

  if [ "$OutParamName__" == "" ];then  Error_func  "出力変数名が指定されていません"  ;fi

  for name__  in "${LocalNames__[@]}" ;do
    if [ "$OutParamName__" == "$name__" ];then
      a1__="<ERROR msg=\"ローカル変数名が衝突しています\" "
      a1__="${a1__}local=\"$name__\"/>"
      Error_func  "$a1__"
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [CheckEvalParamIsConflictToLocal_func] >>> 
#//*********************************************************************
function  CheckEvalParamIsConflictToLocal_func()
{
  local  EvalExpression="$1"
  shift  1
  local  LocalNames=( "$@" )
  local  name
  local  s

  for name  in "${LocalNames[@]}" ;do
    if [ "${EvalExpression%%$name*}" != "$EvalExpression"  ];then
      s="<ERROR msg=\"ローカル変数名が衝突している可能性があります\" "
      s="${s}local=\"$name\"/>"
      Error_func  "$s"
    fi
  done ; done_func $?
}


 
#//*********************************************************************
#// <<< [Assert_func] >>> 
#//*********************************************************************
function  Assert_func()
{
  local  Expression__="$*"
  local  is_pass__
  local  message__
  local  result__

  eval  ' if [ '"$Expression__"' ]; then  is_pass__=1  ;else  is_pass__=0 ;fi '

  if [ "$is_pass__" == "0" ];then  result__="`eval  echo "$Expression__"`"  ;fi

  if false; then  #// ture, if debug
    echo  "<Assert_func"  >&2
    echo  "Expression__='$Expression__'"  >&2
    echo  "result__='$result__'"  >&2
    echo  "is_pass__='$is_pass__'/>"  >&2
  fi

  if [ "$is_pass__" == "0" ];then
    message__=`echo -n "<ERROR msg=\"Assert failed\"><Expression><![CDATA[${LF}$Expression__${LF}]]></Expression>"`
    if [ "$Expression__" != "$result__" ];then
      message__="$message__"`echo -n "<Result><![CDATA[${LF}$result__${LF}]]></Result>"`
    fi
    message__="$message__</ERROR>"
    Error_func  "$message__"
  fi
}


 
#//*********************************************************************
#// <<< [TryStart_func] >>> 
#// <<< [TryEnd1_func] >>> 
#// <<< [TryEnd2_func] >>> 
#//*********************************************************************
function  TryStart_func()
{
  true
  g_Err_NestLevel=$(( $g_Err_NestLevel + 1 ))
}

function  TryEnd1_func()
{
  break
}

function  TryEnd2_func()
{
  CheckArgCount_func  1  "$@"
  if [ "$g_ExitStatus" == "0" ];then
    g_ExitStatus=$1
  fi
  g_Err_NestLevel=$(( $g_Err_NestLevel - 1 ))
  g_Err_Desc1st="$g_Err_Desc"
}


 
#//*********************************************************************
#// <<< [ErrTrap_func] >>> 
#//*********************************************************************

g_ExitStatus=0
g_Ret=""
g_Ret2=""
g_Ret3=""
g_Err_IsDone=0
g_Err_IsOverwrite=0
g_Err_NestLevel=0
g_Err_ErrID=0
g_Err_Desc=""
g_Err_Desc1st=""
g_Err_LineNo="???"
g_PipeStatus=""
g_DebugTrapFunc=""

function  ErrTrap_func()
{
  local  a1

  if [ "$g_Err_IsDone" == "1" ];then
    g_Err_IsDone=0
  elif [ "$g_Err_IsOverwrite" == "1" ];then
    g_Err_IsOverwrite=0
  else

    g_Err_ErrID=$(( $g_Err_ErrID + 1 ))

    if [ "$g_ExitStatus" == "0" ];then
      if [ "$g_Err_LineNo" == "???" ];then  g_Err_LineNo=$1  ;fi
      if [ "$g_Err_LineNo" == "???" ]; then
        a1="${a1}（ヒント）現在の行番号は、${FUNCNAME[1]} 関数の最初で \"EchoOn_func\" を呼ぶと表示されます。${LF}"
      fi
      a1="${a1}（開発者向けヒント）ステップ実行したいときは、開始するところから \"debugger\" 関数を呼び出してください。 "
      a1="${a1}下記コールツリーの最も下の関数が、\` \` を使って echo 出力を取得しているときは、取得しないようにすると、更にコール先の関数が表示されます。${LF}"
      ErrClass.getCallTree_method  "$g_Err_LineNo"  2  1
      g_Err_ErrCallStack="$a1$g_Ret$LF"
    else
      echo  "<ERROR msg=\"エラー処理中に別のエラーが発生しました。\"/>" >&2

      ErrClass.getErrStr_method  "$g_Err_Desc"
      if [ "$g_Ret" == "" ];then  g_Ret="<ERROR/>"  ;fi
      ColorText_func  "$g_Ret"  "Red" "Bold"
      echo_e_func  "$g_Ret"

      ErrClass.getCallTree_method  "${BASH_LINENO[0]}"  2  1
      echo  "$g_Ret"  >&2
      g_Err_Desc="$g_Err_Desc1st"
    fi
  fi
}


 
#//*********************************************************************
#// <<< [done_func] >>> 
#//*********************************************************************
function  done_func()
{
  CheckArgCount_func  1 "$@"
  if [ "$1" != "0" ];then  g_Err_IsDone=1  ;fi
  return  "$1"  #// if not 0, throw again
}


 
#//*********************************************************************
#// <<< [ErrClass.raiseOverwrite_method] >>> 
#//*********************************************************************
function  ErrClass.raiseOverwrite_method()
{
  local  message ; ErrClass.getErrStr_method  "$@" ; message="$g_Ret"
  local  exit_status="$g_ExitStatus"

  if [ "$message" != "" ];then
    g_Err_Desc="$message"
  fi

  if [ "$exit_status" == "0" ];then
    exit_status=1
  fi

  g_Err_IsOverwrite=1
  return  $exit_status
}


 
#//*********************************************************************
#// <<< [ErrClass.clear_method] >>> 
#//*********************************************************************
function  ErrClass.clear_method()
{
  g_ExitStatus=0
  g_Err_Desc=""
  g_Err_Desc1st=""
  g_Err_LineNo="???"
  g_PipeStatus=""
}


 
#//*********************************************************************
#// <<< [ErrClass.getErrStr_method] >>> 
#//*********************************************************************
function  ErrClass.getErrStr_method()
{
  local  Message="$@"

  if [ "$Message" != "" ]; then
    if [ "${Message%%<ERROR *}" == "" ]; then
      g_Ret="$Message"
    else
      StringClass.replace_method  "$Message"  "&"  "&amp;"
      StringClass.replace_method  "$g_Ret"  "<"  "&lt;"
      StringClass.replace_method  "$g_Ret"  "\""  "&quot;"
      g_Ret="<ERROR msg=\"$g_Ret\"/>"
    fi
  else
    g_Ret=""
  fi
}


 
#//*********************************************************************
#// <<< [ErrClass.getCallTree_method] >>> 
#//*********************************************************************
function  ErrClass.getCallTree_method()
{
  local  LineNo="$1"
  local  TopIndex="$2"
  local  IsAbleLastCut="$3"
  local  indent=" "
  local  s

  s="コールツリー："
  i=$(( ${#FUNCNAME[@]} - 1 ))
  s="$s${LF}""(global) ${BASH_SOURCE[$i]}:${BASH_LINENO[$i-1]}"
  for(( i=${#FUNCNAME[@]} - 2; i > $TopIndex; i-- ));do
    s="$s${LF}${indent}${FUNCNAME[$i]}() ${BASH_SOURCE[$i]}:${BASH_LINENO[$i-1]}"
    indent="${indent} "
  done ; done_func $?

  case  "${FUNCNAME[$TopIndex]}"  in
    "Error_func" | "DebugTrap_func" ) ;;
    *)  IsAbleLastCut=0 ;;
  esac
  if [ "$IsAbleLastCut" != "1" ];then
    if [ "$g_DebugTrapFunc" == "EchoOnTrap_func" ];then
      s="$s${LF}${indent}${FUNCNAME[$TopIndex]}() ${BASH_SOURCE[$TopIndex]}:$LineNo ?(->EchoOn_func)"
    else
      s="$s${LF}${indent}${FUNCNAME[$TopIndex]}() ${BASH_SOURCE[$TopIndex]}:$LineNo"
    fi
  fi
  g_Ret="$s"
}


 
#//*********************************************************************
#// <<< [Exit_func] >>> 
#//*********************************************************************
function  Exit_func()
{
  g_DebugTrapFunc=""
  trap ':' EXIT
  exit $ret
}


 
#//*********************************************************************
#// <<< [g_ArrayLength] >>> 
#//*********************************************************************
g_ArrayLength=0


 
#//*********************************************************************
#// <<< [g_AssociativeArrayMaxLength] >>> 
#//*********************************************************************
if [ "$g_AssociativeArrayMaxLength" == "" ];then  g_AssociativeArrayMaxLength=100  ;fi

g_AssociativeArrayLength=0
for (( i = 0; i < $g_AssociativeArrayMaxLength; i ++ ));do
  $declare_AssociativeArrayClass  g_AssociativeArrays_$i
done


 
#//*********************************************************************
#// <<< [LF] >>> 
#// <<< [Tab] >>> 
#//*********************************************************************
LF=`echo_e_func "\nx"`; LF="${LF:0:1}"
Tab=`echo_e_func "\t"`


 
