public static function set($name, $value = null, $range = null, $overwrite=true)
    {
        static::_init();
        
        $range = $range ?: self::$range;
        if (!isset(self::$data[$range])) {
            self::$data->set($range, []);
        }
        
        if (!$name && is_array($value)) {
            foreach ($value as $k => $v) {
                self::set($k, $v, $range, $overwrite);
            }
            return self::$data[$range];
        } elseif (is_string($name)) {
            $old = static::$data->get($range);
            if (!strpos($name, '.')) {
                $temp = [$name => $value];
                
                if ($overwrite || !isset($old[$name])) {
                    $new = ArrayHelper::merge($old, $temp);
                    static::$data->set($range, $new);
                }
                
                return self::$data[$range][$name];
            } else {
                // has '.'
                $names = explode('.', $name, 2);
                $temp = [$names[0] => [$names[1] => $value]];
                
                if ($overwrite || !isset( $old[$names[0]][$names[1]] )) {
                    $new = ArrayHelper::merge($old, $temp);
                    static::$data->set($range, $new);
                }
                
                return self::$data[$range][$names[0]][$names[1]];
            }
        } elseif (is_array($name)) {
            // batch set
            if (!empty($value) && is_string($value)) {
                return static::set($value, $name, null, $overwrite);
            } else {
                foreach ($name as $k => $v){
                    self::set($k, $v, $range, $overwrite);
                }
                return self::$data[$range];
            }
        } else {
            // if no name return config
            return self::$data[$range];
        }
    }