@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Object parse(String source) throws Exception {

		// Parse source
		Tree node = new Tree();
		LinkedProperties properties = new LinkedProperties();
		properties.load(new StringReader(source));
		LinkedHashMap<Object, Object> map = properties.map;

		final HashMap<String, Boolean> zeroIndexes = new HashMap<>();
		final HashMap<String, Boolean> arrays = new HashMap<>();

		// Convert Map to Node
		final StringBuilder path = new StringBuilder();
		for (Map.Entry<Object, Object> entry : map.entrySet()) {
			String key = (String) entry.getKey();
			String value = (String) entry.getValue();

			final StringTokenizer st = new StringTokenizer(key, ". ");
			path.setLength(0);
			while (st.hasMoreTokens()) {
				String token = st.nextToken();

				String prefix = path.toString();
				Boolean array = arrays.get(prefix);

				boolean number;
				if (array != null && !array) {
					number = false;
				} else {
					number = isNumeric(token);
				}

				if (number && array == null) {

					// Analyze array
					array = true;
					final ArrayList<Integer> indexes = new ArrayList<>();
					for (Object o : map.keySet()) {
						String t = (String) o;
						if (t.startsWith(prefix)) {
							int l = prefix.length() + 1;
							int i = t.indexOf('.', l);
							if (i > -1) {
								t = t.substring(l, i);
							} else {
								t = t.substring(l);
							}
							if (isNumeric(t)) {
								int idx = Integer.parseInt(t);
								if (indexes.contains(idx) && i == -1) {

									// Double index!
									array = false;
									break;
								}
								indexes.add(idx);
							} else {

								// Not numeric!
								array = false;
								break;
							}
						}
					}

					// Check index sequence (1,2,3,etc.)
					Collections.sort(indexes);
					int prev = Integer.MIN_VALUE;
					for (int idx : indexes) {
						if (prev == Integer.MIN_VALUE) {

							// First element is not "0" or "1"
							if (idx != 0 && idx != 1) {
								array = false;
								break;
							}

						} else if (prev - idx > 1) {

							// Not sequential!
							array = false;
							break;
						}
						prev = idx;
					}

					arrays.put(prefix, array);
					if (array) {
						String test = prefix + ".0";
						boolean zeroIndex = false;
						for (Object o : map.keySet()) {
							if (((String) o).startsWith(test)) {
								zeroIndex = true;
								break;
							}
						}
						zeroIndexes.put(prefix, zeroIndex);
					} else {
						number = false;
					}
				}

				if (number) {
					path.append('[');
					int idx = Integer.parseInt(token);
					if (!zeroIndexes.get(prefix)) {
						idx--;
					}
					path.append(idx);
					path.append(']');
				} else {
					if (path.length() > 0) {
						path.append('.');
					}
					path.append(token);
				}

			}
			node.put(path.toString(), (String) value);
		}

		// Store first indexes in metadata block
		Object result = node.asObject();
		if (!zeroIndexes.isEmpty()) {
			Tree meta = node.getMeta();
			Tree indexMap = meta.putMap(FIRST_INDEX);
			for (Map.Entry<String, Boolean> entry : zeroIndexes.entrySet()) {
				indexMap.put(entry.getKey(), entry.getValue() ? 0 : 1);
			}

			// Pushback metadata into the value map
			if (result instanceof Map) {
				((Map) result).put(Config.META, meta.asObject());
			}
		}
		return result;
	}
@ SuppressWarnings ( { "rawtypes" , "unchecked" } ) @ Override public Object parse ( String source ) throws Exception { Tree node = new Tree ( ) ; LinkedProperties properties = new LinkedProperties ( ) ; properties . load ( new StringReader ( source ) ) ; LinkedHashMap < Object , Object > map = properties . map ; final HashMap < String , Boolean > zeroIndexes = new HashMap < > ( ) ; final HashMap < String , Boolean > arrays = new HashMap < > ( ) ; final StringBuilder path = new StringBuilder ( ) ; for ( Map . Entry < Object , Object > entry : map . entrySet ( ) ) { String key = ( String ) entry . getKey ( ) ; String value = ( String ) entry . getValue ( ) ; final StringTokenizer st = new StringTokenizer ( key , ". " ) ; path . setLength ( 0 ) ; while ( st . hasMoreTokens ( ) ) { String token = st . nextToken ( ) ; String prefix = path . toString ( ) ; Boolean array = arrays . get ( prefix ) ; boolean number ; if ( array != null && ! array ) { number = false ; } else { number = isNumeric ( token ) ; } if ( number && array == null ) { array = true ; final ArrayList < Integer > indexes = new ArrayList < > ( ) ; for ( Object o : map . keySet ( ) ) { String t = ( String ) o ; if ( t . startsWith ( prefix ) ) { int l = prefix . length ( ) + 1 ; int i = t . indexOf ( '.' , l ) ; if ( i > - 1 ) { t = t . substring ( l , i ) ; } else { t = t . substring ( l ) ; } if ( isNumeric ( t ) ) { int idx = Integer . parseInt ( t ) ; if ( indexes . contains ( idx ) && i == - 1 ) { array = false ; break ; } indexes . add ( idx ) ; } else { array = false ; break ; } } } Collections . sort ( indexes ) ; int prev = Integer . MIN_VALUE ; for ( int idx : indexes ) { if ( prev == Integer . MIN_VALUE ) { if ( idx != 0 && idx != 1 ) { array = false ; break ; } } else if ( prev - idx > 1 ) { array = false ; break ; } prev = idx ; } arrays . put ( prefix , array ) ; if ( array ) { String test = prefix + ".0" ; boolean zeroIndex = false ; for ( Object o : map . keySet ( ) ) { if ( ( ( String ) o ) . startsWith ( test ) ) { zeroIndex = true ; break ; } } zeroIndexes . put ( prefix , zeroIndex ) ; } else { number = false ; } } if ( number ) { path . append ( '[' ) ; int idx = Integer . parseInt ( token ) ; if ( ! zeroIndexes . get ( prefix ) ) { idx -- ; } path . append ( idx ) ; path . append ( ']' ) ; } else { if ( path . length ( ) > 0 ) { path . append ( '.' ) ; } path . append ( token ) ; } } node . put ( path . toString ( ) , ( String ) value ) ; } Object result = node . asObject ( ) ; if ( ! zeroIndexes . isEmpty ( ) ) { Tree meta = node . getMeta ( ) ; Tree indexMap = meta . putMap ( FIRST_INDEX ) ; for ( Map . Entry < String , Boolean > entry : zeroIndexes . entrySet ( ) ) { indexMap . put ( entry . getKey ( ) , entry . getValue ( ) ? 0 : 1 ) ; } if ( result instanceof Map ) { ( ( Map ) result ) . put ( Config . META , meta . asObject ( ) ) ; } } return result ; }
--- IMPLEMENTED PARSER METHOD ---