public static Command.Descriptor DESCRIPTOR(List<Command.Descriptor> descriptors) {
		return new Command.Descriptor() {

			@Override
			public Schema getConfigurationSchema() {
				// TODO Auto-generated method stub
				return null;
			}

			@Override
			public List<Option.Descriptor> getOptionDescriptors() {
				return Arrays.asList(
						Command.OPTION_FLAG("verbose", "generate verbose information about the build", false),
						Command.OPTION_FLAG("brief", "generate brief output for syntax errors", false));
			}

			@Override
			public Command initialise(Command environment, Configuration configuration) {
				return new WyProject((WyMain) environment, configuration, System.out, System.err);
			}

			@Override
			public String getName() {
				return "wy";
			}

			@Override
			public String getDescription() {
				return "Command-line interface for the Whiley Compiler Collection";
			}

			@Override
			public List<Command.Descriptor> getCommands() {
				return descriptors;
			}
		};
	}

The descriptor for this command.

@author David J. Pearce


public Path.Root getRepositoryRoot() throws IOException {
		Path.Root root = environment.getGlobalRoot().createRelativeRoot(REPOSITORY_PATH);
		// TODO: create repository if it doesn't exist.
		return root;
	}

Get the root of the package repository. This is the global directory in which
all installed packages are found.

@return
@throws IOException

Get the root of the package repository . This is the global directory in which all installed packages are found .


private void resolvePackageDependencies() throws IOException {
		// FIXME: should produce a wy.lock file?
		Configuration.Schema buildSchema = environment.getBuildSchema();
		// Global root is where all dependencies will be stored
		Path.Root repository = getRepositoryRoot();
		// Dig out all the defined dependencies
		List<Path.ID> deps = configuration.matchAll(Trie.fromString("dependencies/**"));
		// Resolve each dependencies and add to project roots
		for (int i = 0; i != deps.size(); ++i) {
			Path.ID dep = deps.get(i);
			// Get dependency name
			String name = dep.get(1);
			// Get version string
			UTF8 version = configuration.get(UTF8.class, dep);
			// Construct path to the config file
			Trie root = Trie.fromString(name + "-v" + version);
			// Attempt to resolve it.
			if (!repository.exists(root, ZipFile.ContentType)) {
				// TODO: employ a package resolver here
				// FIXME: handle better error handling.
				throw new RuntimeException("missing dependency \"" + name + "-" + version + "\"");
			} else {
				// Extract entry for ZipFile
				Path.Entry<ZipFile> zipfile = repository.get(root, ZipFile.ContentType);
				// Construct root repesenting this ZipFile
				Path.Root pkgRoot = new ZipFileRoot(zipfile, environment.getContentRegistry());
				// Extract configuration from package
				Path.Entry<ConfigFile> entry = pkgRoot.get(Trie.fromString("wy"),ConfigFile.ContentType);
				if(entry == null) {
					throw new RuntimeException("corrupt package (missing wy.toml) \"" + name + "-" + version + "\"");
				} else {
					ConfigFile pkgcfg = pkgRoot.get(Trie.fromString("wy"),ConfigFile.ContentType).read();
					// Construct a package representation of this root.
					Build.Package pkg = new Package(pkgRoot,pkgcfg.toConfiguration(buildSchema));
					// Add a relative ZipFile root
					project.getPackages().add(pkg);
				}
			}
		}
	}

Add any declared dependencies to the set of project roots. The challenge here
is that we may need to download, install and compile these dependencies if
they are not currently installed.

@throws IOException

Add any declared dependencies to the set of project roots . The challenge here is that we may need to download install and compile these dependencies if they are not currently installed .


public List<Token> scan() {
		ArrayList<Token> tokens = new ArrayList<>();
		pos = 0;

		while (pos < input.length()) {
			char c = input.charAt(pos);

			if (Character.isDigit(c)) {
				tokens.add(scanNumericConstant());
			} else if (c == '"') {
				tokens.add(scanStringConstant());
			} else if (c == '\'') {
				tokens.add(scanCharacterConstant());
			} else if (isOperatorStart(c)) {
				tokens.add(scanOperator());
			} else if (Character.isLetter(c) || c == '_') {
				tokens.add(scanIdentifier());
			} else if (Character.isWhitespace(c)) {
				scanWhiteSpace(tokens);
			} else {
				syntaxError("unknown token encountered",pos);
			}
		}

		return tokens;
	}

public
List
<
Token
>
scan
(
)
{
ArrayList
<
Token
>
tokens
=
new
ArrayList
<>
(
)
;
pos
=
0
;
while
(
pos
<
input
.
length
(
)
)
{
char
c
=
input
.
charAt
(
pos
)
;
if
(
Character
.
isDigit
(
c
)
)
{
tokens
.
add
(
scanNumericConstant
(
)
)
;
}
else
if
(
c
==
'
'
)
{
tokens
.
add
(
scanStringConstant
(
)
)
;
}
else
if
(
c
==
'
'
)
{
tokens
.
add
(
scanCharacterConstant
(
)
)
;
}
else
if
(
isOperatorStart
(
c
)
)
{
tokens
.
add
(
scanOperator
(
)
)
;
}
else
if
(
Character
.
isLetter
(
c
)
||
c
==
'
'
)
{
tokens
.
add
(
scanIdentifier
(
)
)
;
}
else
if
(
Character
.
isWhitespace
(
c
)
)
{
scanWhiteSpace
(
tokens
)
;
}
else
{
syntaxError
(
"unknown token encountered"
,
pos
)
;
}
}
return
tokens
;
}

Scan all characters from the input stream and generate a corresponding
list of tokens, whilst discarding all whitespace and comments.

@return

Scan all characters from the input stream and generate a corresponding list of tokens whilst discarding all whitespace and comments .


private void syntaxError(String msg, int index) {
		// FIXME: this is clearly not a sensible approach
		throw new SyntacticException(msg, entry, new ConfigFile.Attribute.Span(null,index,index));

	}

Raise a syntax error with a given message at given index.

@param msg
--- message to raise.
@param index
--- index position to associate the error with.

Raise a syntax error with a given message at given index .


public void logStackTrace() {
    if (enabled) {
      Throwable t = new Throwable();
      t.fillInStackTrace();
      StackTraceElement[] ste_arr = t.getStackTrace();
      for (int ii = 2; ii < ste_arr.length; ii++) {
        StackTraceElement ste = ste_arr[ii];
        System.out.printf("%s  %s%n", getIndentString(), ste);
      }
    }
  }

public
void
logStackTrace
(
)
{
if
(
enabled
)
{
Throwable
t
=
new
Throwable
(
)
;
t
.
fillInStackTrace
(
)
;
StackTraceElement
[
]
ste_arr
=
t
.
getStackTrace
(
)
;
for
(
int
ii
=
2
;
ii
<
ste_arr
.
length
;
ii
++
)
{
StackTraceElement
ste
=
ste_arr
[
ii
]
;
System
.
out
.
printf
(
"%s  %s%n"
,
getIndentString
(
)
,
ste
)
;
}
}
}


private String getIndentString() {
    assert enabled;
    if (indentString == null) {
      for (int i = indentStrings.size(); i <= indentLevel; i++) {
        indentStrings.add(indentStrings.get(i - 1) + INDENT_STR_ONE_LEVEL);
      }
      indentString = indentStrings.get(indentLevel);
    }
    return indentString;
  }

private String getIndentString ( ) { assert enabled ; if ( indentString == null ) { for ( int i = indentStrings . size ( ) ; i <= indentLevel ; i ++ ) { indentStrings . add ( indentStrings . get ( i - 1 ) + INDENT_STR_ONE_LEVEL ) ; } indentString = indentStrings . get ( indentLevel ) ; } return indentString ; }


boolean execute(
      InstructionContext ic,
      Frame inFrame,
      ArrayList<InstructionContext> executionPredecessors,
      InstConstraintVisitor icv,
      ExecutionVisitor ev) {
    stack_types.set(ic.getInstruction().getPosition(), inFrame);
    return ic.execute(inFrame, executionPredecessors, icv, ev);
  }

boolean execute ( InstructionContext ic , Frame inFrame , ArrayList < InstructionContext > executionPredecessors , InstConstraintVisitor icv , ExecutionVisitor ev ) { stack_types . set ( ic . getInstruction ( ) . getPosition ( ) , inFrame ) ; return ic . execute ( inFrame , executionPredecessors , icv , ev ) ; }

Like InstructionContext.execute, but also sets stack_types.

Like InstructionContext . execute but also sets stack_types .


protected String[] add_string(String[] arr, String new_string) {
    String[] new_arr = new String[arr.length + 1];
    for (int ii = 0; ii < arr.length; ii++) {
      new_arr[ii] = arr[ii];
    }
    new_arr[arr.length] = new_string;
    return new_arr;
  }

protected String [ ] add_string ( String [ ] arr , String new_string ) { String [ ] new_arr = new String [ arr . length + 1 ] ; for ( int ii = 0 ; ii < arr . length ; ii ++ ) { new_arr [ ii ] = arr [ ii ] ; } new_arr [ arr . length ] = new_string ; return new_arr ; }

Returns a String array with new_string added to the end of arr.

@param arr original string array
@param new_string string to be added
@return the new string array

Returns a String array with new_string added to the end of arr .


@Pure
  protected final String get_attribute_name(Attribute a) {
    int con_index = a.getNameIndex();
    Constant c = pool.getConstant(con_index);
    String att_name = ((ConstantUtf8) c).getBytes();
    return att_name;
  }

@ Pure protected final String get_attribute_name ( Attribute a ) { int con_index = a . getNameIndex ( ) ; Constant c = pool . getConstant ( con_index ) ; String att_name = ( ( ConstantUtf8 ) c ) . getBytes ( ) ; return att_name ; }

Return the attribute name for the specified attribute.

@param a the attribute
@return the attribute name for the specified attribute

Return the attribute name for the specified attribute .


@Pure
  protected final @Nullable Attribute get_stack_map_table_attribute(MethodGen mgen) {
    for (Attribute a : mgen.getCodeAttributes()) {
      if (is_stack_map_table(a)) {
        return a;
      }
    }
    return null;
  }

@ Pure protected final @ Nullable Attribute get_stack_map_table_attribute ( MethodGen mgen ) { for ( Attribute a : mgen . getCodeAttributes ( ) ) { if ( is_stack_map_table ( a ) ) { return a ; } } return null ; }

Find the StackMapTable attribute for a method. Return null if there isn't one.

@param mgen the method
@return the StackMapTable attribute for the method (or null if not present)

Find the StackMapTable attribute for a method . Return null if there isn t one .


@Pure
  protected final @Nullable Attribute get_local_variable_type_table_attribute(MethodGen mgen) {
    for (Attribute a : mgen.getCodeAttributes()) {
      if (is_local_variable_type_table(a)) {
        return a;
      }
    }
    return null;
  }

@ Pure protected final @ Nullable Attribute get_local_variable_type_table_attribute ( MethodGen mgen ) { for ( Attribute a : mgen . getCodeAttributes ( ) ) { if ( is_local_variable_type_table ( a ) ) { return a ; } } return null ; }

Find the LocalVariableTypeTable attribute for a method. Return null if there isn't one.

@param mgen the method
@return the LocalVariableTypeTable attribute for the method (or null if not present)

Find the LocalVariableTypeTable attribute for a method . Return null if there isn t one .


protected final StackMapEntry find_stack_map_equal(int offset) {

    running_offset = -1; // no +1 on first entry
    for (int i = 0; i < stack_map_table.length; i++) {
      running_offset = stack_map_table[i].getByteCodeOffset() + running_offset + 1;

      if (running_offset > offset) {
        throw new RuntimeException("Invalid StackMap offset 1");
      }

      if (running_offset == offset) {
        return stack_map_table[i];
      }
      // try next map entry
    }

    // no offset matched
    throw new RuntimeException("Invalid StackMap offset 2");
  }

protected
final
StackMapEntry
find_stack_map_equal
(
int
offset
)
{
running_offset
=
1
;
// no +1 on first entry
for
(
int
i
=
0
;
i
<
stack_map_table
.
length
;
i
++
)
{
running_offset
=
stack_map_table
[
i
]
.
getByteCodeOffset
(
)
+
running_offset
+
1
;
if
(
running_offset
>
offset
)
{
throw
new
RuntimeException
(
"Invalid StackMap offset 1"
)
;
}
if
(
running_offset
==
offset
)
{
return
stack_map_table
[
i
]
;
}
// try next map entry
}
// no offset matched
throw
new
RuntimeException
(
"Invalid StackMap offset 2"
)
;
}

Find the StackMap entry whose offset matches the input argument. Also sets running_offset.

@param offset byte code offset
@return the corresponding StackMapEntry

Find the StackMap entry whose offset matches the input argument . Also sets running_offset .


protected final int find_stack_map_index_before(int offset) {

    number_active_locals = initial_locals_count;
    running_offset = -1; // no +1 on first entry
    for (int i = 0; i < stack_map_table.length; i++) {
      running_offset = running_offset + stack_map_table[i].getByteCodeOffset() + 1;
      if (running_offset >= offset) {
        if (i == 0) {
          // reset offset to previous
          running_offset = -1;
          return -1;
        } else {
          // back up offset to previous
          running_offset = running_offset - stack_map_table[i].getByteCodeOffset() - 1;
          // return previous
          return i - 1;
        }
      }

      // Update number of active locals based on this StackMap entry.
      int frame_type = stack_map_table[i].getFrameType();
      if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) {
        number_active_locals += frame_type - 251;
      } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) {
        number_active_locals -= 251 - frame_type;
      } else if (frame_type == Const.FULL_FRAME) {
        number_active_locals = stack_map_table[i].getNumberOfLocals();
      }
      // All other frame_types do not modify locals.
    }

    if (stack_map_table.length == 0) {
      return -1;
    } else {
      return stack_map_table.length - 1;
    }
  }

Find the index of the StackMap entry whose offset is the last one before the input argument.
Return -1 if there isn't one. Also sets running_offset and number_active_locals.

@param offset byte code offset
@return the corresponding StackMapEntry index

Find the index of the StackMap entry whose offset is the last one before the input argument . Return - 1 if there isn t one . Also sets running_offset and number_active_locals .


protected final @IndexOrLow("stack_map_table") int find_stack_map_index_after(int offset) {

    running_offset = -1; // no +1 on first entry
    for (int i = 0; i < stack_map_table.length; i++) {
      running_offset = running_offset + stack_map_table[i].getByteCodeOffset() + 1;
      if (running_offset > offset) {
        return i;
      }
      // try next map entry
    }

    // no such entry found
    return -1;
  }

protected
final
@
IndexOrLow
(
"stack_map_table"
)
int
find_stack_map_index_after
(
int
offset
)
{
running_offset
=
1
;
// no +1 on first entry
for
(
int
i
=
0
;
i
<
stack_map_table
.
length
;
i
++
)
{
running_offset
=
running_offset
+
stack_map_table
[
i
]
.
getByteCodeOffset
(
)
+
1
;
if
(
running_offset
>
offset
)
{
return
i
;
}
// try next map entry
}
// no such entry found
return
1
;
}

Find the index of the StackMap entry whose offset is the first one after the input argument.
Return -1 if there isn't one. Also sets running_offset.

@param offset byte code offset
@return the corresponding StackMapEntry index

Find the index of the StackMap entry whose offset is the first one after the input argument . Return - 1 if there isn t one . Also sets running_offset .


protected final void build_unitialized_NEW_map(InstructionList il) {

    uninitialized_NEW_map.clear();
    il.setPositions();

    for (StackMapEntry smte : stack_map_table) {
      int frame_type = smte.getFrameType();

      if ((frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME
              && frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
          || (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX)
          || (frame_type == Const.FULL_FRAME)) {

        if (smte.getNumberOfLocals() > 0) {
          for (StackMapType smt : smte.getTypesOfLocals()) {
            if (smt.getType() == Const.ITEM_NewObject) {
              int i = smt.getIndex();
              uninitialized_NEW_map.put(il.findHandle(i), i);
            }
          }
        }
        if (smte.getNumberOfStackItems() > 0) {
          for (StackMapType smt : smte.getTypesOfStackItems()) {
            if (smt.getType() == Const.ITEM_NewObject) {
              int i = smt.getIndex();
              uninitialized_NEW_map.put(il.findHandle(i), i);
            }
          }
        }
      }
    }
  }

protected final void build_unitialized_NEW_map ( InstructionList il ) { uninitialized_NEW_map . clear ( ) ; il . setPositions ( ) ; for ( StackMapEntry smte : stack_map_table ) { int frame_type = smte . getFrameType ( ) ; if ( ( frame_type >= Const . SAME_LOCALS_1_STACK_ITEM_FRAME && frame_type <= Const . SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED ) || ( frame_type >= Const . APPEND_FRAME && frame_type <= Const . APPEND_FRAME_MAX ) || ( frame_type == Const . FULL_FRAME ) ) { if ( smte . getNumberOfLocals ( ) > 0 ) { for ( StackMapType smt : smte . getTypesOfLocals ( ) ) { if ( smt . getType ( ) == Const . ITEM_NewObject ) { int i = smt . getIndex ( ) ; uninitialized_NEW_map . put ( il . findHandle ( i ) , i ) ; } } } if ( smte . getNumberOfStackItems ( ) > 0 ) { for ( StackMapType smt : smte . getTypesOfStackItems ( ) ) { if ( smt . getType ( ) == Const . ITEM_NewObject ) { int i = smt . getIndex ( ) ; uninitialized_NEW_map . put ( il . findHandle ( i ) , i ) ; } } } } } }

We need to locate and remember any NEW instructions that create uninitialized objects. Their
offset may be contained in a StackMap entry and will probably need to be updated as we add
instrumentation code. Note that these instructions are fairly rare.

@param il instruction list to search

We need to locate and remember any NEW instructions that create uninitialized objects . Their offset may be contained in a StackMap entry and will probably need to be updated as we add instrumentation code . Note that these instructions are fairly rare .


private final void update_NEW_object_stack_map_entries(int old_offset, int new_offset) {

    for (StackMapEntry smte : stack_map_table) {
      int frame_type = smte.getFrameType();

      if ((frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME
              && frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
          || (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX)
          || (frame_type == Const.FULL_FRAME)) {

        if (smte.getNumberOfLocals() > 0) {
          for (StackMapType smt : smte.getTypesOfLocals()) {
            if (smt.getType() == Const.ITEM_NewObject) {
              if (old_offset == smt.getIndex()) {
                smt.setIndex(new_offset);
              }
            }
          }
        }
        if (smte.getNumberOfStackItems() > 0) {
          for (StackMapType smt : smte.getTypesOfStackItems()) {
            if (smt.getType() == Const.ITEM_NewObject) {
              if (old_offset == smt.getIndex()) {
                smt.setIndex(new_offset);
              }
            }
          }
        }
      }
    }
  }

private final void update_NEW_object_stack_map_entries ( int old_offset , int new_offset ) { for ( StackMapEntry smte : stack_map_table ) { int frame_type = smte . getFrameType ( ) ; if ( ( frame_type >= Const . SAME_LOCALS_1_STACK_ITEM_FRAME && frame_type <= Const . SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED ) || ( frame_type >= Const . APPEND_FRAME && frame_type <= Const . APPEND_FRAME_MAX ) || ( frame_type == Const . FULL_FRAME ) ) { if ( smte . getNumberOfLocals ( ) > 0 ) { for ( StackMapType smt : smte . getTypesOfLocals ( ) ) { if ( smt . getType ( ) == Const . ITEM_NewObject ) { if ( old_offset == smt . getIndex ( ) ) { smt . setIndex ( new_offset ) ; } } } } if ( smte . getNumberOfStackItems ( ) > 0 ) { for ( StackMapType smt : smte . getTypesOfStackItems ( ) ) { if ( smt . getType ( ) == Const . ITEM_NewObject ) { if ( old_offset == smt . getIndex ( ) ) { smt . setIndex ( new_offset ) ; } } } } } } }

One of uninitialized NEW instructions has moved. Update its offset in StackMap entries. Note
that more than one entry could refer to the same instruction. This is a helper routine used by
update_uninitialized_NEW_offsets.

@param old_offset original location of NEW instruction
@param new_offset new location of NEW instruction

One of uninitialized NEW instructions has moved . Update its offset in StackMap entries . Note that more than one entry could refer to the same instruction . This is a helper routine used by update_uninitialized_NEW_offsets .


protected final void update_uninitialized_NEW_offsets(InstructionList il) {

    il.setPositions();

    for (Map.Entry<InstructionHandle, Integer> e : uninitialized_NEW_map.entrySet()) {
      InstructionHandle ih = e.getKey();
      int old_offset = e.getValue().intValue();
      int new_offset = ih.getPosition();
      if (old_offset != new_offset) {
        update_NEW_object_stack_map_entries(old_offset, new_offset);
        e.setValue(new_offset);
      }
    }
  }

protected final void update_uninitialized_NEW_offsets ( InstructionList il ) { il . setPositions ( ) ; for ( Map . Entry < InstructionHandle , Integer > e : uninitialized_NEW_map . entrySet ( ) ) { InstructionHandle ih = e . getKey ( ) ; int old_offset = e . getValue ( ) . intValue ( ) ; int new_offset = ih . getPosition ( ) ; if ( old_offset != new_offset ) { update_NEW_object_stack_map_entries ( old_offset , new_offset ) ; e . setValue ( new_offset ) ; } } }

Check to see if any of the uninitialized NEW instructions have moved. Again, these are rare, so
a linear pass is fine.

@param il instruction list to search

Check to see if any of the uninitialized NEW instructions have moved . Again these are rare so a linear pass is fine .


@EnsuresNonNull({"stack_map_table"})
  protected final void set_current_stack_map_table(MethodGen mgen, int java_class_version) {

    smta = (StackMap) get_stack_map_table_attribute(mgen);
    if (smta != null) {
      // get a deep copy of the original StackMapTable.
      stack_map_table = ((StackMap) (smta.copy(smta.getConstantPool()))).getStackMap();
      needStackMap = true;

      debug_instrument.log(
          "Attribute tag: %s length: %d nameIndex: %d%n",
          smta.getTag(), smta.getLength(), smta.getNameIndex());
      // Delete existing stack map - we'll add a new one later.
      mgen.removeCodeAttribute(smta);
    } else {
      stack_map_table = empty_stack_map_table;
      if (java_class_version > Const.MAJOR_1_6) {
        needStackMap = true;
      }
    }
    print_stack_map_table("Original");
  }

Get existing StackMapTable from the MethodGen argument. If there is none, create a new empty
one. Sets both smta and stack_map_table. Must be called prior to any other methods that
manipulate the stack_map_table!

@param mgen MethodGen to search
@param java_class_version Java version for the classfile; stack_map_table is optional before
Java 1.7 (= classfile version 51)

Get existing StackMapTable from the MethodGen argument . If there is none create a new empty one . Sets both smta and stack_map_table . Must be called prior to any other methods that manipulate the stack_map_table!


protected final void print_stack_map_table(String prefix) {

    debug_instrument.log("%nStackMap(%s) %s items:%n", prefix, stack_map_table.length);
    running_offset = -1; // no +1 on first entry
    for (int i = 0; i < stack_map_table.length; i++) {
      running_offset = stack_map_table[i].getByteCodeOffset() + running_offset + 1;
      debug_instrument.log("@%03d %s %n", running_offset, stack_map_table[i]);
    }
  }

protected
final
void
print_stack_map_table
(
String
prefix
)
{
debug_instrument
.
log
(
"%nStackMap(%s) %s items:%n"
,
prefix
,
stack_map_table
.
length
)
;
running_offset
=
1
;
// no +1 on first entry
for
(
int
i
=
0
;
i
<
stack_map_table
.
length
;
i
++
)
{
running_offset
=
stack_map_table
[
i
]
.
getByteCodeOffset
(
)
+
running_offset
+
1
;
debug_instrument
.
log
(
"@%03d %s %n"
,
running_offset
,
stack_map_table
[
i
]
)
;
}
}

Print the contents of the StackMapTable to the debug_instrument.log.

@param prefix label to display with table

Print the contents of the StackMapTable to the debug_instrument . log .


protected final void create_new_stack_map_attribute(MethodGen mgen) throws IOException {

    if (!needStackMap) {
      return;
    }
    if (stack_map_table == empty_stack_map_table) {
      return;
    }
    print_stack_map_table("Final");

    // Build new StackMapTable attribute
    StackMap map_table =
        new StackMap(pool.addUtf8("StackMapTable"), 0, null, pool.getConstantPool());
    map_table.setStackMap(stack_map_table);
    mgen.addCodeAttribute(map_table);
  }

protected
final
void
create_new_stack_map_attribute
(
MethodGen
mgen
)
throws
IOException
{
if
(
!
needStackMap
)
{
return
;
}
if
(
stack_map_table
==
empty_stack_map_table
)
{
return
;
}
print_stack_map_table
(
"Final"
)
;
// Build new StackMapTable attribute
StackMap
map_table
=
new
StackMap
(
pool
.
addUtf8
(
"StackMapTable"
)
,
0
,
,
pool
.
getConstantPool
(
)
)
;
map_table
.
setStackMap
(
stack_map_table
)
;
mgen
.
addCodeAttribute
(
map_table
)
;
}

Create a new StackMap code attribute from stack_map_table.

@param mgen MethodGen to add attribute to
@throws IOException if cannot create the attribute

Create a new StackMap code attribute from stack_map_table .


@SuppressWarnings("signature") // conversion routine
  protected static @ClassGetName String typeToClassGetName(Type t) {

    if (t instanceof ObjectType) {
      return ((ObjectType) t).getClassName();
    } else if (t instanceof BasicType) {
      // Use reserved keyword for basic type rather than signature to
      // avoid conflicts with user defined types.
      return t.toString();
    } else {
      // Array type: just convert '/' to '.'
      return t.getSignature().replace('/', '.');
    }
  }

Convert a Type name to a Class name.

@param t type whose name is to be converted
@return a String containing the class name


protected final StackMapType generate_StackMapType_from_Type(Type t) {

    switch (t.getType()) {
      case Const.T_BOOLEAN:
      case Const.T_CHAR:
      case Const.T_BYTE:
      case Const.T_SHORT:
      case Const.T_INT:
        return new StackMapType(Const.ITEM_Integer, -1, pool.getConstantPool());
      case Const.T_FLOAT:
        return new StackMapType(Const.ITEM_Float, -1, pool.getConstantPool());
      case Const.T_DOUBLE:
        return new StackMapType(Const.ITEM_Double, -1, pool.getConstantPool());
      case Const.T_LONG:
        return new StackMapType(Const.ITEM_Long, -1, pool.getConstantPool());
      case Const.T_ARRAY:
      case Const.T_OBJECT:
        return new StackMapType(
            Const.ITEM_Object, pool.addClass(typeToClassGetName(t)), pool.getConstantPool());
        // UNKNOWN seems to be used for Uninitialized objects.
        // The second argument to the constructor should be the code offset
        // of the corresponding 'new' instruction.  Just using 0 for now.
      case Const.T_UNKNOWN:
        return new StackMapType(Const.ITEM_NewObject, 0, pool.getConstantPool());
      default:
        throw new RuntimeException("Invalid type: " + t + t.getType());
    }
  }

Convert a Type to a StackMapType.

@param t Type to be converted
@return result StackMapType


protected final Type generate_Type_from_StackMapType(StackMapType smt) {

    switch (smt.getType()) {
      case Const.ITEM_Integer:
      case Const.ITEM_Bogus: // not sure about this; reresents 'top'?
        return Type.INT;
      case Const.ITEM_Float:
        return Type.FLOAT;
      case Const.ITEM_Double:
        return Type.DOUBLE;
      case Const.ITEM_Long:
        return Type.LONG;
      case Const.ITEM_Object:
        return Type.OBJECT;
      default:
        Thread.dumpStack();
        assert false : "Invalid StackMapType: " + smt + smt.getType();
        throw new RuntimeException("Invalid StackMapType: " + smt + smt.getType());
    }
  }

Convert a StackMapType to a Type.

@param smt StackMapType to be converted
@return result Type


protected final LocalVariableGen create_method_scope_local(
      MethodGen mgen, String local_name, Type local_type) {
    // BCEL sorts local vars and presents them in offset order.  Search
    // locals for first var with start != 0. If none, just add the new
    // var at the end of the table and exit. Otherwise, insert the new
    // var just prior to the local we just found.
    // Now we need to make a pass over the byte codes to update the local
    // offset values of all the locals we just shifted up.  This may have
    // a 'knock on' effect if we are forced to change an instruction that
    // references implict local #3 to an instruction with an explict
    // reference to local #4 as this would require the insertion of an
    // offset into the byte codes. This means we would need to make an
    // additional pass to update branch targets (no - BCEL does this for
    // us) and the StackMapTable (yes - BCEL should do this, but it doesn't).
    //
    // We never want to insert our local prior to any parameters.  This would
    // happen naturally, but some old class files have non zero addresses
    // for 'this' and/or the parameters so we need to add an explicit
    // check to make sure we skip these variables.

    LocalVariableGen lv_new;
    int max_offset = 0;
    int new_offset = -1;
    // get a copy of the local before modification
    LocalVariableGen[] locals = mgen.getLocalVariables();
    @IndexOrLow("locals") int compiler_temp_i = -1;
    int new_index = -1;
    int i;

    for (i = 0; i < locals.length; i++) {
      LocalVariableGen lv = locals[i];
      if (i >= first_local_index) {
        if (lv.getStart().getPosition() != 0) {
          if (new_offset == -1) {
            if (compiler_temp_i != -1) {
              new_offset = locals[compiler_temp_i].getIndex();
              new_index = compiler_temp_i;
            } else {
              new_offset = lv.getIndex();
              new_index = i;
            }
          }
        }
      }

      // calculate max local size seen so far (+1)
      max_offset = lv.getIndex() + lv.getType().getSize();

      if (lv.getName().startsWith("DaIkOnTeMp")) {
        // Remember the index of a compiler temp.  We may wish
        // to insert our new local prior to a temp to simplfy
        // the generation of StackMaps.
        if (compiler_temp_i == -1) {
          compiler_temp_i = i;
        }
      } else {
        // If there were compiler temps prior to this local, we don't
        // need to worry about them as the compiler will have already
        // included them in the StackMaps. Reset the indicators.
        compiler_temp_i = -1;
      }
    }

    // We have looked at all the local variables; if we have not found
    // a place for our new local, check to see if last local was a
    // compiler temp and insert prior.
    if ((new_offset == -1) && (compiler_temp_i != -1)) {
      new_offset = locals[compiler_temp_i].getIndex();
      new_index = compiler_temp_i;
    }

    // If new_offset is still unset, we can just add our local at the
    // end.  There may be unnamed compiler temps here, so we need to
    // check for this (via max_offset) and move them up.
    if (new_offset == -1) {
      new_offset = max_offset;
      if (new_offset < mgen.getMaxLocals()) {
        mgen.setMaxLocals(mgen.getMaxLocals() + local_type.getSize());
      }
      lv_new = mgen.addLocalVariable(local_name, local_type, new_offset, null, null);
    } else {
      // insert our new local variable into existing table at 'new_offset'
      lv_new = mgen.addLocalVariable(local_name, local_type, new_offset, null, null);
      // we need to adjust the offset of any locals after our insertion
      for (i = new_index; i < locals.length; i++) {
        LocalVariableGen lv = locals[i];
        lv.setIndex(lv.getIndex() + local_type.getSize());
      }
      mgen.setMaxLocals(mgen.getMaxLocals() + local_type.getSize());
    }

    debug_instrument.log(
        "Added local  %s%n", lv_new.getIndex() + ": " + lv_new.getName() + ", " + lv_new.getType());

    // Now process the instruction list, adding one to the offset
    // within each LocalVariableInstruction that references a
    // local that is 'higher' in the local map than new local
    // we just inserted.
    adjust_code_for_locals_change(mgen, new_offset, local_type.getSize());

    // Finally, we need to update any FULL_FRAME StackMap entries to
    // add in the new local variable type.
    update_full_frame_stack_map_entries(new_offset, local_type, locals);

    debug_instrument.log("New LocalVariableTable:%n%s%n", mgen.getLocalVariableTable(pool));
    return lv_new;
  }

Create a new local with a scope of the full method. This means we need to search the existing
locals to find the proper index for our new local. This might have the side effect of causing
us to rewrite the method byte codes to adjust the offsets for the existing local variables -
see below for details.

<p>Must call fix_local_variable_table (just once per method) before calling this routine.

@param mgen MethodGen to be modified
@param local_name name of new local
@param local_type type of new local
@return a LocalVariableGen for the new local

Create a new local with a scope of the full method . This means we need to search the existing locals to find the proper index for our new local . This might have the side effect of causing us to rewrite the method byte codes to adjust the offsets for the existing local variables - see below for details .


protected final StackTypes bcel_calc_stack_types(MethodGen mg) {

    StackVer stackver = new StackVer();
    VerificationResult vr;
    try {
      vr = stackver.do_stack_ver(mg);
    } catch (Throwable t) {
      System.out.printf("Warning: StackVer exception for %s.%s%n", mg.getClassName(), mg.getName());
      System.out.printf("Exception: %s%n", t);
      System.out.printf("Method is NOT instrumented%n");
      return null;
    }
    if (vr != VerificationResult.VR_OK) {
      System.out.printf(
          "Warning: StackVer failed for %s.%s: %s%n", mg.getClassName(), mg.getName(), vr);
      System.out.printf("Method is NOT instrumented%n");
      return null;
    }
    assert vr == VerificationResult.VR_OK : " vr failed " + vr;
    return stackver.get_stack_types();
  }

Calculates the types on the stack for each instruction using the BCEL stack verification
routines.

@param mg MethodGen for the method to be analyzed
@return a StackTypes object for the method

Calculates the types on the stack for each instruction using the BCEL stack verification routines .


static String accessFlagsToString(Method m) {

    int flags = m.getAccessFlags();

    StringBuilder buf = new StringBuilder();
    // Note that pow is a binary mask for the flag (= 2^i).
    for (int i = 0, pow = 1; i <= Const.MAX_ACC_FLAG; i++) {
      if ((flags & pow) != 0) {
        if (buf.length() > 0) {
          buf.append(" ");
        }
        if (i < Const.ACCESS_NAMES_LENGTH) {
          buf.append(Const.getAccessName(i));
        } else {
          buf.append(String.format("ACC_BIT(%x)", pow));
        }
      }
      pow <<= 1;
    }

    return buf.toString();
  }

Return a string representation of the access flags of method m. In the string, the flags are
space-separated and in a canonical order.

@param m the method whose access flags to retrieve
@return a string representation of the access flags of method m

Return a string representation of the access flags of method m . In the string the flags are space - separated and in a canonical order .


public static String instructionListToString(InstructionList il, ConstantPoolGen pool) {

    StringBuilder out = new StringBuilder();
    for (Iterator<InstructionHandle> i = il.iterator(); i.hasNext(); ) {
      InstructionHandle handle = i.next();
      out.append(handle.getInstruction().toString(pool.getConstantPool()) + "\n");
    }
    return out.toString();
  }

public static String instructionListToString ( InstructionList il , ConstantPoolGen pool ) { StringBuilder out = new StringBuilder ( ) ; for ( Iterator < InstructionHandle > i = il . iterator ( ) ; i . hasNext ( ) ; ) { InstructionHandle handle = i . next ( ) ; out . append ( handle . getInstruction ( ) . toString ( pool . getConstantPool ( ) ) + "\n" ) ; } return out . toString ( ) ; }

Return a printed description of the given instructions.

@param il the instructions to describe
@param pool the constant pool the instructions refer to
@return a printed representation of the instructions in {@code il}

Return a printed description of the given instructions .


public static String attributeNameToString(Attribute a) {

    ConstantPool pool = a.getConstantPool();
    int conIndex = a.getNameIndex();
    Constant c = pool.getConstant(conIndex);
    String attName = ((ConstantUtf8) c).getBytes();
    return attName;
  }

public static String attributeNameToString ( Attribute a ) { ConstantPool pool = a . getConstantPool ( ) ; int conIndex = a . getNameIndex ( ) ; Constant c = pool . getConstant ( conIndex ) ; String attName = ( ( ConstantUtf8 ) c ) . getBytes ( ) ; return attName ; }

Return the attribute name for the specified attribute, looked up in the original class file
ConstantPool.

@param a the attribute
@return the attribute name for the specified attribute

Return the attribute name for the specified attribute looked up in the original class file ConstantPool .


public static void checkMgen(MethodGen mgen) {

    if (skipChecks) {
      return;
    }

    try {
      mgen.toString(); // ensure it can be formatted without exceptions
      mgen.getLineNumberTable(mgen.getConstantPool());

      InstructionList ilist = mgen.getInstructionList();
      if (ilist == null || ilist.getStart() == null) {
        return;
      }
      CodeExceptionGen[] exceptionHandlers = mgen.getExceptionHandlers();
      for (CodeExceptionGen gen : exceptionHandlers) {
        assert ilist.contains(gen.getStartPC())
            : "exception handler "
                + gen
                + " has been forgotten in "
                + mgen.getClassName()
                + "."
                + mgen.getName();
      }
      MethodGen nmg = new MethodGen(mgen.getMethod(), mgen.getClassName(), mgen.getConstantPool());
      nmg.getLineNumberTable(mgen.getConstantPool());
    } catch (Throwable t) {
      Error e =
          new Error(
              String.format(
                  "failure while checking method %s.%s%n", mgen.getClassName(), mgen.getName()),
              t);
      e.printStackTrace();
      throw e;
    }
  }

Checks the specified method for consistency.

<p>Does nothing if {@link #skipChecks} is false.

@param mgen the class to check

Checks the specified method for consistency .


public static void checkMgens(final ClassGen gen) {

    if (skipChecks) {
      return;
    }

    Method[] methods = gen.getMethods();
    for (int i = 0; i < methods.length; i++) {
      Method method = methods[i];
      // System.out.println ("Checking method " + method + " in class "
      // + gen.getClassName());
      checkMgen(new MethodGen(method, gen.getClassName(), gen.getConstantPool()));
    }

    // Diagnostic output
    if (false) {
      dumpStackTrace();
      dumpMethods(gen);
    }
  }

Checks all of the methods in gen for consistency.

@param gen the class to check

Checks all of the methods in gen for consistency .


public static void dumpStackTrace() {

    StackTraceElement[] ste = Thread.currentThread().getStackTrace();
    // [0] is getStackTrace
    // [1] is dumpStackTrace
    if (ste.length < 3) {
      System.out.println("No stack trace information available");
    } else {
      StackTraceElement caller = ste[2];
      System.out.printf(
          "%s.%s (%s line %d)",
          caller.getClassName(),
          caller.getMethodName(),
          caller.getFileName(),
          caller.getLineNumber());
      for (int ii = 3; ii < ste.length; ii++) {
        System.out.printf(" [%s line %d]", ste[ii].getFileName(), ste[ii].getLineNumber());
      }
      System.out.printf("%n");
    }
  }

public
static
void
dumpStackTrace
(
)
{
StackTraceElement
[
]
ste
=
Thread
.
currentThread
(
)
.
getStackTrace
(
)
;
// [0] is getStackTrace
// [1] is dumpStackTrace
if
(
ste
.
length
<
3
)
{
System
.
out
.
println
(
"No stack trace information available"
)
;
}
else
{
StackTraceElement
caller
=
ste
[
2
]
;
System
.
out
.
printf
(
"%s.%s (%s line %d)"
,
caller
.
getClassName
(
)
,
caller
.
getMethodName
(
)
,
caller
.
getFileName
(
)
,
caller
.
getLineNumber
(
)
)
;
for
(
int
ii
=
3
;
ii
<
ste
.
length
;
ii
++
)
{
System
.
out
.
printf
(
" [%s line %d]"
,
ste
[
ii
]
.
getFileName
(
)
,
ste
[
ii
]
.
getLineNumber
(
)
)
;
}
System
.
out
.
printf
(
"%n"
)
;
}
}


static void dumpMethods(ClassGen gen) {

    System.out.printf("Class %s methods:%n", gen.getClassName());
    for (Method m : gen.getMethods()) {
      System.out.printf("  %s%n", m);
    }
  }

static
void
dumpMethods
(
ClassGen
gen
)
{
System
.
out
.
printf
(
"Class %s methods:%n"
,
gen
.
getClassName
(
)
)
;
for
(
Method
m
:
gen
.
getMethods
(
)
)
{
System
.
out
.
printf
(
"  %s%n"
,
m
)
;
}
}

Print the methods in the class, to standard output.

@param gen the class whose methods to print

Print the methods in the class to standard output .


public static void addToStart(MethodGen mg, InstructionList newList) {

    // Add the code before the first instruction
    InstructionList il = mg.getInstructionList();
    InstructionHandle oldStart = il.getStart();
    InstructionHandle newStart = il.insert(newList);

    // Move any LineNumbers and local variables that currently point to
    // the first instruction to include the new instructions. Other
    // targeters (branches, exceptions) should not include the new code.
    if (oldStart.hasTargeters()) {
      // getTargeters() returns non-null because hasTargeters => true
      for (InstructionTargeter it : oldStart.getTargeters()) {
        if ((it instanceof LineNumberGen) || (it instanceof LocalVariableGen)) {
          it.updateTarget(oldStart, newStart);
        }
      }
    }
    mg.setMaxStack();
    mg.setMaxLocals();
  }

Adds instructions to the start of a method.

@param mg method to be augmented
@param newList instructions to prepend to the method

Adds instructions to the start of a method .


public static String getConstantString(ConstantPool pool, int index) {

    Constant c = pool.getConstant(index);
    assert c != null : "Bad index " + index + " into pool";
    if (c instanceof ConstantUtf8) {
      return ((ConstantUtf8) c).getBytes();
    } else if (c instanceof ConstantClass) {
      ConstantClass cc = (ConstantClass) c;
      return cc.getBytes(pool) + " [" + cc.getNameIndex() + "]";
    } else {
      throw new Error("unexpected constant " + c + " of class " + c.getClass());
    }
  }

public
static
String
getConstantString
(
ConstantPool
pool
,
int
index
)
{
Constant
c
=
pool
.
getConstant
(
index
)
;
assert
c
!=
:
"Bad index "
+
index
+
" into pool"
;
if
(
c
instanceof
ConstantUtf8
)
{
return
(
(
ConstantUtf8
)
c
)
.
getBytes
(
)
;
}
else
if
(
c
instanceof
ConstantClass
)
{
ConstantClass
cc
=
(
ConstantClass
)
c
;
return
cc
.
getBytes
(
pool
)
+
" ["
+
cc
.
getNameIndex
(
)
+
"]"
;
}
else
{
throw
new
Error
(
"unexpected constant "
+
c
+
" of class "
+
c
.
getClass
(
)
)
;
}
}

Returns the constant string at the specified offset.

@param pool the constant pool
@param index the index in the constant pool
@return the constant string at the specified offset in the constant pool

Returns the constant string at the specified offset .


public static void resetLocalsToFormals(MethodGen mg) {

    // Get the parameter types and names.
    @SuppressWarnings("nullness" // The annotation arguments might not be initialized yet.
    // Since the arguments are not executed at run time, there is no null pointer exception.
    )
    Type @SameLen({"argTypes", "mg.getArgumentTypes()"}) [] argTypes = mg.getArgumentTypes();
    @SuppressWarnings("nullness" // The annotation arguments might not be initialized yet.
    // Since the arguments are not executed at run time, there is no null pointer exception.
    )
    String @SameLen({"argTypes", "argNames", "mg.getArgumentTypes()", "mg.getArgumentNames()"}) []
        argNames = mg.getArgumentNames();

    // Remove any existing locals
    mg.setMaxLocals(0);
    mg.removeLocalVariables();

    // Add a local for the instance variable (this)
    if (!mg.isStatic()) {
      mg.addLocalVariable("this", new ObjectType(mg.getClassName()), null, null);
    }

    // Add a local for each parameter
    for (int ii = 0; ii < argNames.length; ii++) {
      mg.addLocalVariable(argNames[ii], argTypes[ii], null, null);
    }

    // Reset the current number of locals so that when other locals
    // are added they get added at the correct offset.
    mg.setMaxLocals();

    return;
  }

Sets the locals to be the formal parameters. Any other locals are removed. An instruction list
with at least one instruction must exist.

@param mg the method whose locals to set

Sets the locals to be the formal parameters . Any other locals are removed . An instruction list with at least one instruction must exist .


public static Class<?> typeToClass(Type type) {

    String classname = typeToClassgetname(type);
    try {
      return ReflectionPlume.classForName(classname);
    } catch (Exception e) {
      throw new RuntimeException("can't find class for " + classname, e);
    }
  }

public
static
Class
<
>
typeToClass
(
Type
type
)
{
String
classname
=
typeToClassgetname
(
type
)
;
try
{
return
ReflectionPlume
.
classForName
(
classname
)
;
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"can't find class for "
+
classname
,
e
)
;
}
}

Returns the class that corresponds to type.

@param type the type
@return the Java class that corresponds to type

Returns the class that corresponds to type .


public static Type[] postpendToArray(Type[] types, Type newType) {
    if (types.length == Integer.MAX_VALUE) {
      throw new Error("array " + types + " is too large to extend");
    }
    Type[] newTypes = new Type[types.length + 1];
    System.arraycopy(types, 0, newTypes, 0, types.length);
    newTypes[types.length] = newType;
    return newTypes;
  }

public
static
Type
[
]
postpendToArray
(
Type
[
]
types
,
Type
newType
)
{
if
(
types
.
length
==
Integer
.
MAX_VALUE
)
{
throw
new
Error
(
"array "
+
types
+
" is too large to extend"
)
;
}
Type
[
]
newTypes
=
new
Type
[
types
.
length
+
1
]
;
System
.
arraycopy
(
types
,
0
,
newTypes
,
0
,
types
.
length
)
;
newTypes
[
types
.
length
]
=
newType
;
return
newTypes
;
}

Returns a copy of the given type array, with newType added to the end.

@param types the array to extend
@param newType the element to add to the end of the array
@return a new array, with newType at the end

Returns a copy of the given type array with newType added to the end .


public void set(@IndexFor({"loc_arr", "os_arr"}) int offset, Frame f) {

    OperandStack os = f.getStack();
    // logger.info ("stack[" + offset + "] = " + toString(os));

    loc_arr[offset] = (LocalVariables) (f.getLocals().clone());
    os_arr[offset] = (OperandStack) (os.clone());
  }

Sets the stack for the instruction at the specified offset to a copy of the information in the
given frame.

@param offset the offset at which the instruction appears
@param f the stack frame to use for the instruction

Sets the stack for the instruction at the specified offset to a copy of the information in the given frame .


protected final void insert_at_method_start(MethodGen mg, InstructionList new_il) {

    // Ignore methods with no instructions
    InstructionList il = mg.getInstructionList();
    if (il == null) {
      return;
    }
    insert_before_handle(mg, il.getStart(), new_il, false);
  }

protected
final
void
insert_at_method_start
(
MethodGen
mg
,
InstructionList
new_il
)
{
// Ignore methods with no instructions
InstructionList
il
=
mg
.
getInstructionList
(
)
;
if
(
il
==
)
{
return
;
}
insert_before_handle
(
mg
,
il
.
getStart
(
)
,
new_il
,
false
)
;
}

Inserts an instruction list at the beginning of a method.

@param mg MethodGen of method to be modified
@param new_il InstructionList holding the new code

Inserts an instruction list at the beginning of a method .


private void print_il(InstructionHandle start, String label) {
    if (debug_instrument.enabled()) {
      print_stack_map_table(label);
      InstructionHandle tih = start;
      while (tih != null) {
        debug_instrument.log("inst: %s %n", tih);
        if (tih.hasTargeters()) {
          for (InstructionTargeter it : tih.getTargeters()) {
            debug_instrument.log("targeter: %s %n", it);
          }
        }
        tih = tih.getNext();
      }
    }
  }

private
void
print_il
(
InstructionHandle
start
,
String
label
)
{
if
(
debug_instrument
.
enabled
(
)
)
{
print_stack_map_table
(
label
)
;
InstructionHandle
tih
=
start
;
while
(
tih
!=
)
{
debug_instrument
.
log
(
"inst: %s %n"
,
tih
)
;
if
(
tih
.
hasTargeters
(
)
)
{
for
(
InstructionTargeter
it
:
tih
.
getTargeters
(
)
)
{
debug_instrument
.
log
(
"targeter: %s %n"
,
it
)
;
}
}
tih
=
tih
.
getNext
(
)
;
}
}
}

Print a BCEL instruction list to the debug_instrument log.

@param start start of the instruction list
@param label a descriptive string for the instruction list

Print a BCEL instruction list to the debug_instrument log .


protected final InstructionList build_il(Instruction... instructions) {
    InstructionList il = new InstructionList();
    for (Instruction inst : instructions) {
      append_inst(il, inst);
    }
    return il;
  }

protected final InstructionList build_il ( Instruction ... instructions ) { InstructionList il = new InstructionList ( ) ; for ( Instruction inst : instructions ) { append_inst ( il , inst ) ; } return il ; }

Convenience function to build an instruction list.

@param instructions a variable number of BCEL instructions
@return an InstructionList

Convenience function to build an instruction list .


protected final StackMapType[] calculate_live_stack_types(OperandStack stack) {
    int ss = stack.size();
    StackMapType[] stack_map_types = new StackMapType[ss];
    for (int ii = 0; ii < ss; ii++) {
      stack_map_types[ii] = generate_StackMapType_from_Type(stack.peek(ss - ii - 1));
    }
    return stack_map_types;
  }

protected final StackMapType [ ] calculate_live_stack_types ( OperandStack stack ) { int ss = stack . size ( ) ; StackMapType [ ] stack_map_types = new StackMapType [ ss ] ; for ( int ii = 0 ; ii < ss ; ii ++ ) { stack_map_types [ ii ] = generate_StackMapType_from_Type ( stack . peek ( ss - ii - 1 ) ) ; } return stack_map_types ; }

Compute the StackMapTypes of the items on the execution stack as described by the OperandStack
argument.

@param stack an OperandStack object
@return an array of StackMapType describing the stack contents

Compute the StackMapTypes of the items on the execution stack as described by the OperandStack argument .


private static final int find(boolean skipBlocks, String s, char toFind, int from) {
		int open = 0;
		boolean escaping = false;
		for (int i = from; i < s.length(); i++) {
			if (escaping) {
				escaping = false;
				continue;
			}
			char c = s.charAt(i);
			if (c == '\\') {
				escaping = true;
				continue;
			}
			if ((open == 0) && (c == toFind)) {
				return i;
			} else if (skipBlocks && (c == '{')) {
				open++;
			} else if (skipBlocks && (c == '}')) {
				open--;
			}
		}
		return -1;
	}

private static final int find ( boolean skipBlocks , String s , char toFind , int from ) { int open = 0 ; boolean escaping = false ; for ( int i = from ; i < s . length ( ) ; i ++ ) { if ( escaping ) { escaping = false ; continue ; } char c = s . charAt ( i ) ; if ( c == ' ' ) { escaping = true ; continue ; } if ( ( open == 0 ) && ( c == toFind ) ) { return i ; } else if ( skipBlocks && ( c == ' ' ) ) { open ++ ; } else if ( skipBlocks && ( c == ' ' ) ) { open -- ; } } return - 1 ; }

Beware, with the current algorithm, this function cannot find '\'

Beware with the current algorithm this function cannot find \


@Override
    public int read(final byte[] output, final int offset, final int length) throws TTransportException {
        int read = 0;
        int index = offset;
        int space = length - offset;
        while (space > 0) {
            byte aByte = readAsynchrously();
            output[index] = aByte;
            space--;
            index++;
            read++;
        }
        return read;
    }

@ Override public int read ( final byte [ ] output , final int offset , final int length ) throws TTransportException { int read = 0 ; int index = offset ; int space = length - offset ; while ( space > 0 ) { byte aByte = readAsynchrously ( ) ; output [ index ] = aByte ; space -- ; index ++ ; read ++ ; } return read ; }

Reads from the shared input queue, blocking if there is not enough input
in the buffer. It's the only way we can emulate the synchronous nature of
TTransport using netty.

Reads from the shared input queue blocking if there is not enough input in the buffer . It s the only way we can emulate the synchronous nature of TTransport using netty .


@Override
    public void flush() throws TTransportException {
        ChannelBuffer flush = ChannelBuffers.dynamicBuffer();
        flush.writeBytes(output);
        channel.write(flush).awaitUninterruptibly();
    }

@ Override public void flush ( ) throws TTransportException { ChannelBuffer flush = ChannelBuffers . dynamicBuffer ( ) ; flush . writeBytes ( output ) ; channel . write ( flush ) . awaitUninterruptibly ( ) ; }

We need data to be written and flushed at once.

We need data to be written and flushed at once .


public WebSocketClient newClient(final URI url, final WebSocketCallback callback) {
        ClientBootstrap bootstrap = new ClientBootstrap(socketChannelFactory);

        String protocol = url.getScheme();
        if (!protocol.equals("ws") && !protocol.equals("wss")) {
            throw new IllegalArgumentException("Unsupported protocol: " + protocol);
        }

        final WebSocketClientHandler clientHandler = new WebSocketClientHandler(bootstrap, url, callback);

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = Channels.pipeline();
                pipeline.addLast("decoder", new HttpResponseDecoder());
                pipeline.addLast("encoder", new HttpRequestEncoder());
                pipeline.addLast("ws-handler", clientHandler);
                return pipeline;
            }
        });

        return clientHandler;
    }

public
WebSocketClient
newClient
(
final
URI
url
,
final
WebSocketCallback
callback
)
{
ClientBootstrap
bootstrap
=
new
ClientBootstrap
(
socketChannelFactory
)
;
String
protocol
=
url
.
getScheme
(
)
;
if
(
!
protocol
.
equals
(
"ws"
)
&&
!
protocol
.
equals
(
"wss"
)
)
{
throw
new
IllegalArgumentException
(
"Unsupported protocol: "
+
protocol
)
;
}
final
WebSocketClientHandler
clientHandler
=
new
WebSocketClientHandler
(
bootstrap
,
url
,
callback
)
;
bootstrap
.
setPipelineFactory
(
new
ChannelPipelineFactory
(
)
{
public
ChannelPipeline
getPipeline
(
)
throws
Exception
{
ChannelPipeline
pipeline
=
Channels
.
pipeline
(
)
;
pipeline
.
addLast
(
"decoder"
,
new
HttpResponseDecoder
(
)
)
;
pipeline
.
addLast
(
"encoder"
,
new
HttpRequestEncoder
(
)
)
;
pipeline
.
addLast
(
"ws-handler"
,
clientHandler
)
;
return
pipeline
;
}
}
)
;
return
clientHandler
;
}

Create a new WebSocket client
@param url URL to connect to.
@param callback Callback interface to receive events
@return A WebSocket client. Call {@link WebSocketClient#connect()} to connect.


private boolean canUseThisAd(NativeAd adNative) {
        if (adNative != null) {
            NativeAd.Image logoImage = null;
            CharSequence header = null, body = null;
            if (adNative instanceof NativeContentAd) {
                NativeContentAd ad = (NativeContentAd) adNative;
                logoImage = ad.getLogo();
                header = ad.getHeadline();
                body = ad.getBody();
            } else if (adNative instanceof NativeAppInstallAd) {
                NativeAppInstallAd ad = (NativeAppInstallAd) adNative;
                logoImage = ad.getIcon();
                header = ad.getHeadline();
                body = ad.getBody();
            }

            if (!TextUtils.isEmpty(header)
                    && !TextUtils.isEmpty(body)) {
                return true;
            }
        }
        return false;
    }

private boolean canUseThisAd ( NativeAd adNative ) { if ( adNative != null ) { NativeAd . Image logoImage = null ; CharSequence header = null , body = null ; if ( adNative instanceof NativeContentAd ) { NativeContentAd ad = ( NativeContentAd ) adNative ; logoImage = ad . getLogo ( ) ; header = ad . getHeadline ( ) ; body = ad . getBody ( ) ; } else if ( adNative instanceof NativeAppInstallAd ) { NativeAppInstallAd ad = ( NativeAppInstallAd ) adNative ; logoImage = ad . getIcon ( ) ; header = ad . getHeadline ( ) ; body = ad . getBody ( ) ; } if ( ! TextUtils . isEmpty ( header ) && ! TextUtils . isEmpty ( body ) ) { return true ; } } return false ; }

Determines if the native ad can be used.

@param adNative the native ad object
@return true if the ad object can be used, false otherwise

Determines if the native ad can be used .


public synchronized AdView getAdForIndex(int adPos) {
        if(adPos >= 0 && mPrefetchedAds.size() > adPos)
            return mPrefetchedAds.get(adPos);
        return null;
    }

public synchronized AdView getAdForIndex ( int adPos ) { if ( adPos >= 0 && mPrefetchedAds . size ( ) > adPos ) return mPrefetchedAds . get ( adPos ) ; return null ; }

Gets banner ad at a particular index in the fetched ads list.

@param adPos the index of ad in the fetched ads list
@return the banner ad in the list
@see #getFetchedAdsCount()

Gets banner ad at a particular index in the fetched ads list .


private synchronized void onFailedToLoad(AdView adView, int errorCode) {
        Log.i(TAG, "onAdFailedToLoad " + errorCode);
        mFetchFailCount++;
        mNoOfFetchedAds = Math.max(mNoOfFetchedAds - 1, 0);
        //Since Fetch Ad is only called once without retries
        //hide ad row / rollback its count if still not added to list
        mPrefetchedAds.remove(adView);
        onAdFailed(mNoOfFetchedAds - 1, errorCode, adView);
    }

A handler for failed banner ads
@param adView


protected synchronized AdRequest getAdRequest() {
        AdRequest.Builder adBldr = new AdRequest.Builder();
        for (String id : getTestDeviceIds()) {
            adBldr.addTestDevice(id);
        }
        return adBldr.build();
    }

protected synchronized AdRequest getAdRequest ( ) { AdRequest . Builder adBldr = new AdRequest . Builder ( ) ; for ( String id : getTestDeviceIds ( ) ) { adBldr . addTestDevice ( id ) ; } return adBldr . build ( ) ; }


public int getAdsCountToPublish(int fetchedAdsCount, int sourceItemsCount){
        if(fetchedAdsCount <= 0 || getNoOfDataBetweenAds() <= 0) return 0;
        int expected = 0;
        if(sourceItemsCount > 0 && sourceItemsCount >= getOffsetValue()+1)
            expected = (sourceItemsCount - getOffsetValue()) / getNoOfDataBetweenAds() + 1;
        expected = Math.max(0, expected);
        expected = Math.min(fetchedAdsCount, expected);
        return Math.min(expected, getLimitOfAds());
    }

public int getAdsCountToPublish ( int fetchedAdsCount , int sourceItemsCount ) { if ( fetchedAdsCount <= 0 || getNoOfDataBetweenAds ( ) <= 0 ) return 0 ; int expected = 0 ; if ( sourceItemsCount > 0 && sourceItemsCount >= getOffsetValue ( ) + 1 ) expected = ( sourceItemsCount - getOffsetValue ( ) ) / getNoOfDataBetweenAds ( ) + 1 ; expected = Math . max ( 0 , expected ) ; expected = Math . min ( fetchedAdsCount , expected ) ; return Math . min ( expected , getLimitOfAds ( ) ) ; }

Gets the count of ads that could be published

@param fetchedAdsCount the count of completely fetched ads that are ready to be published
@param sourceItemsCount the count of items in the source collection
@return the original position that the adapter position would have been without ads


public int getOriginalContentPosition(int position, int fetchedAdsCount, int sourceItemsCount) {
        int noOfAds = getAdsCountToPublish(fetchedAdsCount, sourceItemsCount);
        // No of spaces for ads in the dataset, according to ad placement rules
        int adSpacesCount = (getAdIndex(position) + 1);
        int originalPosition = position - Math.min(adSpacesCount, noOfAds);
        //Log.d("POSITION", position + " is originally " + originalPosition);
        return originalPosition;
    }

Translates an adapter position to an actual position within the underlying dataset.

@param position the adapter position
@param fetchedAdsCount the count of completely fetched ads that are ready to be published
@param sourceItemsCount the count of items in the source collection
@return the original position that the adapter position would have been without ads

Translates an adapter position to an actual position within the underlying dataset .


public int getAdIndex(int position) {
        int index = -1;
        if(position >= getOffsetValue())
            index = (position - getOffsetValue()) / (getNoOfDataBetweenAds()+1);
        //Log.d("POSITION", "index " + index + " for position " + position);
        return index;
    }

Gets the ad index for this adapter position within the list of currently fetched ads.

@param position the adapter position
@return the index of the ad within the list of fetched ads

Gets the ad index for this adapter position within the list of currently fetched ads .


public boolean isAdAvailable(int position, int fetchedAdsCount) {
        if(fetchedAdsCount == 0) return false;
        int adIndex = getAdIndex(position);
        int firstAdPos = getOffsetValue();

        return position >= firstAdPos && adIndex >= 0 && adIndex < getLimitOfAds() && adIndex < fetchedAdsCount;
    }

public boolean isAdAvailable ( int position , int fetchedAdsCount ) { if ( fetchedAdsCount == 0 ) return false ; int adIndex = getAdIndex ( position ) ; int firstAdPos = getOffsetValue ( ) ; return position >= firstAdPos && adIndex >= 0 && adIndex < getLimitOfAds ( ) && adIndex < fetchedAdsCount ; }

Checks if an ad is available for this position.

@param position the adapter position
@param fetchedAdsCount the count of completely fetched ads that are ready to be published
@return {@code true} if an ad is available, {@code false} otherwise

Checks if an ad is available for this position .


public boolean hasToFetchAd(int position, int fetchingAdsCount){
        int adIndex = getAdIndex(position);
        int firstAdPos = getOffsetValue();
        return  position >= firstAdPos && adIndex >= 0 && adIndex < getLimitOfAds() && adIndex >= fetchingAdsCount;
    }

public boolean hasToFetchAd ( int position , int fetchingAdsCount ) { int adIndex = getAdIndex ( position ) ; int firstAdPos = getOffsetValue ( ) ; return position >= firstAdPos && adIndex >= 0 && adIndex < getLimitOfAds ( ) && adIndex >= fetchingAdsCount ; }

Checks if we have to request the next ad block for this position.

@param position the adapter position
@param fetchingAdsCount the count of fetched and currently fetching ads
@return {@code true} if an ad is not available to publish and we should fetch one, {@code false} otherwise

Checks if we have to request the next ad block for this position .


public static TypeMirror getWildcardType(String type, String elementType, Elements elements,
                                           Types types) {
    TypeElement arrayList = elements.getTypeElement(type);
    TypeMirror elType = elements.getTypeElement(elementType).asType();
    return types.getDeclaredType(arrayList, types.getWildcardType(elType, null));
  }

public static TypeMirror getWildcardType ( String type , String elementType , Elements elements , Types types ) { TypeElement arrayList = elements . getTypeElement ( type ) ; TypeMirror elType = elements . getTypeElement ( elementType ) . asType ( ) ; return types . getDeclaredType ( arrayList , types . getWildcardType ( elType , null ) ) ; }


public static TypeMirror hasGenericsTypeArgumentOf(Element element, String typeToCheck,
                                                     Elements elements, Types types) {

    if (element.asType().getKind() != TypeKind.DECLARED
        || !(element.asType() instanceof DeclaredType)) {
      ProcessorMessage.error(element, "The field %s in %s doesn't have generic type arguments!",
          element.getSimpleName(), element.asType().toString());
    }

    DeclaredType declaredType = (DeclaredType) element.asType();
    List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();

    if (typeArguments.isEmpty()) {
      ProcessorMessage.error(element, "The field %s in %s doesn't have generic type arguments!",
          element.getSimpleName(), element.asType().toString());
    }

    if (typeArguments.size() > 1) {
      ProcessorMessage.error(element, "The field %s in %s has more than 1 generic type argument!",
          element.getSimpleName(), element.asType().toString());
    }

    // Ok it has a generic argument, check if this extends Parcelable
    TypeMirror argument = typeArguments.get(0);

    if (typeToCheck != null) {
      if (!isOfType(argument, typeToCheck, elements, types)) {
        ProcessorMessage.error(element,
            "The fields %s  generic type argument is not of type  %s! (in %s )",
            element.getSimpleName(), typeToCheck, element.asType().toString());
      }
    }

    // everything is like expected
    return argument;
  }

Checks if the variabel element has generics arguments that matches the expected type


public JavaWriter emitPackage(String packageName) throws IOException {
    if (this.packagePrefix != null) {
      throw new IllegalStateException();
    }
    if (packageName.isEmpty()) {
      this.packagePrefix = "";
    } else {
      out.write("package ");
      out.write(packageName);
      out.write(";\n\n");
      this.packagePrefix = packageName + ".";
    }
    return this;
  }

public
JavaWriter
emitPackage
(
String
packageName
)
throws
IOException
{
if
(
this
.
packagePrefix
!=
)
{
throw
new
IllegalStateException
(
)
;
}
if
(
packageName
.
isEmpty
(
)
)
{
this
.
packagePrefix
=
""
;
}
else
{
out
.
write
(
"package "
)
;
out
.
write
(
packageName
)
;
out
.
write
(
";\n\n"
)
;
this
.
packagePrefix
=
packageName
+
"."
;
}
return
this
;
}

Emit a package declaration and empty line.

Emit a package declaration and empty line .


public String compressType(String type) {
    StringBuilder sb = new StringBuilder();
    if (this.packagePrefix == null) {
      throw new IllegalStateException();
    }

    Matcher m = TYPE_PATTERN.matcher(type);
    int pos = 0;
    while (true) {
      boolean found = m.find(pos);

      // Copy non-matching characters like "<".
      int typeStart = found ? m.start() : type.length();
      sb.append(type, pos, typeStart);

      if (!found) {
        break;
      }

      // Copy a single class name, shortening it if possible.
      String name = m.group(0);
      String imported = importedTypes.get(name);
      if (imported != null) {
        sb.append(imported);
      } else if (isClassInPackage(name, packagePrefix)) {
        String compressed = name.substring(packagePrefix.length());
        if (isAmbiguous(compressed)) {
          sb.append(name);
        } else {
          sb.append(compressed);
        }
      } else if (isClassInPackage(name, "java.lang.")) {
        sb.append(name.substring("java.lang.".length()));
      } else {
        sb.append(name);
      }
      pos = m.end();
    }
    return sb.toString();
  }

Try to compress a fully-qualified class name to only the class name.

Try to compress a fully - qualified class name to only the class name .


public JavaWriter beginInitializer(boolean isStatic) throws IOException {
    indent();
    if (isStatic) {
      out.write("static");
      out.write(" {\n");
    } else {
      out.write("{\n");
    }
    scopes.push(Scope.INITIALIZER);
    return this;
  }

public
JavaWriter
beginInitializer
(
boolean
isStatic
)
throws
IOException
{
indent
(
)
;
if
(
isStatic
)
{
out
.
write
(
"static"
)
;
out
.
write
(
" {\n"
)
;
}
else
{
out
.
write
(
"{\n"
)
;
}
scopes
.
push
(
Scope
.
INITIALIZER
)
;
return
this
;
}

Emits an initializer declaration.

@param isStatic true if it should be an static initializer, false for an instance initializer.


public JavaWriter endType() throws IOException {
    popScope(Scope.TYPE_DECLARATION, Scope.INTERFACE_DECLARATION);
    types.pop();
    indent();
    out.write("}\n");
    return this;
  }

public JavaWriter endType ( ) throws IOException { popScope ( Scope . TYPE_DECLARATION , Scope . INTERFACE_DECLARATION ) ; types . pop ( ) ; indent ( ) ; out . write ( "}\n" ) ; return this ; }

Completes the current type declaration .


public JavaWriter emitSingleLineComment(String comment, Object... args) throws IOException {
    indent();
    out.write("// ");
    out.write(String.format(comment, args));
    out.write("\n");
    return this;
  }

public
JavaWriter
emitSingleLineComment
(
String
comment
,
Object
...
args
)
throws
IOException
{
indent
(
)
;
out
.
write
(
"// "
)
;
out
.
write
(
String
.
format
(
comment
,
args
)
)
;
out
.
write
(
"\n"
)
;
return
this
;
}


private JavaWriter emitAnnotationValue(Object value) throws IOException {
    if (value instanceof Object[]) {
      out.write("{");
      boolean firstValue = true;
      scopes.push(Scope.ANNOTATION_ARRAY_VALUE);
      for (Object o : ((Object[]) value)) {
        if (firstValue) {
          firstValue = false;
          out.write("\n");
        } else {
          out.write(",\n");
        }
        indent();
        out.write(o.toString());
      }
      popScope(Scope.ANNOTATION_ARRAY_VALUE);
      out.write("\n");
      indent();
      out.write("}");
    } else {
      out.write(value.toString());
    }
    return this;
  }

private JavaWriter emitAnnotationValue ( Object value ) throws IOException { if ( value instanceof Object [ ] ) { out . write ( "{" ) ; boolean firstValue = true ; scopes . push ( Scope . ANNOTATION_ARRAY_VALUE ) ; for ( Object o : ( ( Object [ ] ) value ) ) { if ( firstValue ) { firstValue = false ; out . write ( "\n" ) ; } else { out . write ( ",\n" ) ; } indent ( ) ; out . write ( o . toString ( ) ) ; } popScope ( Scope . ANNOTATION_ARRAY_VALUE ) ; out . write ( "\n" ) ; indent ( ) ; out . write ( "}" ) ; } else { out . write ( value . toString ( ) ) ; } return this ; }

Writes a single annotation value. If the value is an array, each element in the array will be
written to its own line.

Writes a single annotation value . If the value is an array each element in the array will be written to its own line .


public JavaWriter endMethod() throws IOException {
    Scope popped = scopes.pop();
    // support calling a constructor a "method" to support the legacy code
    if (popped == Scope.NON_ABSTRACT_METHOD || popped == Scope.CONSTRUCTOR) {
      indent();
      out.write("}\n");
    } else if (popped != Scope.ABSTRACT_METHOD) {
      throw new IllegalStateException();
    }
    return this;
  }

Completes the current method declaration.

Completes the current method declaration .


public static String type(Class<?> raw, String... parameters) {
    if (parameters.length == 0) {
      return raw.getCanonicalName();
    }
    if (raw.getTypeParameters().length != parameters.length) {
      throw new IllegalArgumentException();
    }
    StringBuilder result = new StringBuilder();
    result.append(raw.getCanonicalName());
    result.append("<");
    result.append(parameters[0]);
    for (int i = 1; i < parameters.length; i++) {
      result.append(", ");
      result.append(parameters[i]);
    }
    result.append(">");
    return result.toString();
  }

public
static
String
type
(
Class
<
>
raw
,
String
...
parameters
)
{
if
(
parameters
.
length
==
0
)
{
return
raw
.
getCanonicalName
(
)
;
}
if
(
raw
.
getTypeParameters
(
)
.
length
!=
parameters
.
length
)
{
throw
new
IllegalArgumentException
(
)
;
}
StringBuilder
result
=
new
StringBuilder
(
)
;
result
.
append
(
raw
.
getCanonicalName
(
)
)
;
result
.
append
(
"<"
)
;
result
.
append
(
parameters
[
0
]
)
;
for
(
int
i
=
1
;
i
<
parameters
.
length
;
i
++
)
{
result
.
append
(
", "
)
;
result
.
append
(
parameters
[
i
]
)
;
}
result
.
append
(
">"
)
;
return
result
.
toString
(
)
;
}

Build a string representation of a type and optionally its generic type arguments.

Build a string representation of a type and optionally its generic type arguments .


private void emitModifiers(Set<Modifier> modifiers) throws IOException {
    if (modifiers.isEmpty()) {
      return;
    }
    // Use an EnumSet to ensure the proper ordering
    if (!(modifiers instanceof EnumSet)) {
      modifiers = EnumSet.copyOf(modifiers);
    }
    for (Modifier modifier : modifiers) {
      out.append(modifier.toString()).append(' ');
    }
  }


private PsiClass getPsiClassFromContext(AnActionEvent e) {
    PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
    Editor editor = e.getData(PlatformDataKeys.EDITOR);

    if (psiFile == null || editor == null) {
      return null;
    }

    int offset = editor.getCaretModel().getOffset();
    PsiElement element = psiFile.findElementAt(offset);

    return PsiTreeUtil.getParentOfType(element, PsiClass.class);
  }

private PsiClass getPsiClassFromContext ( AnActionEvent e ) { PsiFile psiFile = e . getData ( LangDataKeys . PSI_FILE ) ; Editor editor = e . getData ( PlatformDataKeys . EDITOR ) ; if ( psiFile == null || editor == null ) { return null ; } int offset = editor . getCaretModel ( ) . getOffset ( ) ; PsiElement element = psiFile . findElementAt ( offset ) ; return PsiTreeUtil . getParentOfType ( element , PsiClass . class ) ; }

Get the class where currently the curser is


private void findAndRemoveMethod(String methodName, String... arguments) {
    // Maybe there's an easier way to do this with mClass.findMethodBySignature(), but I'm not an expert on Psi*
    PsiMethod[] methods = psiClass.findMethodsByName(methodName, false);

    for (PsiMethod method : methods) {
      PsiParameterList parameterList = method.getParameterList();

      if (parameterList.getParametersCount() == arguments.length) {
        boolean shouldDelete = true;

        PsiParameter[] parameters = parameterList.getParameters();

        for (int i = 0; i < arguments.length; i++) {
          if (!parameters[i].getType().getCanonicalText().equals(arguments[i])) {
            shouldDelete = false;
          }
        }

        if (shouldDelete) {
          method.delete();
        }
      }
    }
  }

Finds and removes a given method
@param methodName
@param arguments


public void generate() {

    PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject());
    JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(psiClass.getProject());

    // Clear any previous
    clearPrevious();

    // Implements parcelable
    makeClassImplementParcelable(elementFactory, styleManager);

    // @ParcelablePlease Annotation
    addAnnotation(elementFactory, styleManager);

    // Creator
    PsiField creatorField = elementFactory.createFieldFromText(generateCreator(), psiClass);

    // Describe contents method
    PsiMethod describeContentsMethod =
        elementFactory.createMethodFromText(generateDescribeContents(), psiClass);

    // Method for writing to the parcel
    PsiMethod writeToParcelMethod =
        elementFactory.createMethodFromText(generateWriteToParcel(), psiClass);

    styleManager.shortenClassReferences(
        psiClass.addBefore(describeContentsMethod, psiClass.getLastChild()));

    styleManager.shortenClassReferences(
        psiClass.addBefore(writeToParcelMethod, psiClass.getLastChild()));

    styleManager.shortenClassReferences(psiClass.addBefore(creatorField, psiClass.getLastChild()));
  }

public
void
generate
(
)
{
PsiElementFactory
elementFactory
=
JavaPsiFacade
.
getElementFactory
(
psiClass
.
getProject
(
)
)
;
JavaCodeStyleManager
styleManager
=
JavaCodeStyleManager
.
getInstance
(
psiClass
.
getProject
(
)
)
;
// Clear any previous
clearPrevious
(
)
;
// Implements parcelable
makeClassImplementParcelable
(
elementFactory
,
styleManager
)
;
// @ParcelablePlease Annotation
addAnnotation
(
elementFactory
,
styleManager
)
;
// Creator
PsiField
creatorField
=
elementFactory
.
createFieldFromText
(
generateCreator
(
)
,
psiClass
)
;
// Describe contents method
PsiMethod
describeContentsMethod
=
elementFactory
.
createMethodFromText
(
generateDescribeContents
(
)
,
psiClass
)
;
// Method for writing to the parcel
PsiMethod
writeToParcelMethod
=
elementFactory
.
createMethodFromText
(
generateWriteToParcel
(
)
,
psiClass
)
;
styleManager
.
shortenClassReferences
(
psiClass
.
addBefore
(
describeContentsMethod
,
psiClass
.
getLastChild
(
)
)
)
;
styleManager
.
shortenClassReferences
(
psiClass
.
addBefore
(
writeToParcelMethod
,
psiClass
.
getLastChild
(
)
)
)
;
styleManager
.
shortenClassReferences
(
psiClass
.
addBefore
(
creatorField
,
psiClass
.
getLastChild
(
)
)
)
;
}

Generate and insert the Parcel and ParcelablePlease code


private void makeClassImplementParcelable(PsiElementFactory elementFactory, JavaCodeStyleManager styleManager) {
    final PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes();
    final String implementsType = "android.os.Parcelable";

    for (PsiClassType implementsListType : implementsListTypes) {
      PsiClass resolved = implementsListType.resolve();

      // Already implements Parcelable, no need to add it
      if (resolved != null && implementsType.equals(resolved.getQualifiedName())) {
        return;
      }
    }

    PsiJavaCodeReferenceElement implementsReference =
        elementFactory.createReferenceFromText(implementsType, psiClass);
    PsiReferenceList implementsList = psiClass.getImplementsList();

    if (implementsList != null) {
      styleManager.shortenClassReferences(implementsList.add(implementsReference));
    }
  }


private boolean isClass(Element element) {
    if (element.getKind() == ElementKind.CLASS) {

      if (element.getModifiers().contains(Modifier.ABSTRACT)) {
        ProcessorMessage.error(element,
            "Element %s is annotated with @%s but is an abstract class. "
                + "Abstract classes can not be annotated. Annotate the concrete class "
                + "that implements all abstract methods with @%s", element.getSimpleName(),
            ParcelablePlease.class.getSimpleName(), ParcelablePlease.class.getSimpleName());
        return false;
      }

      if (element.getModifiers().contains(Modifier.PRIVATE)) {
        ProcessorMessage.error(element, "The private class %s is annotated with @%s. "
                + "Private classes are not supported because of lacking visibility.",
            element.getSimpleName(), ParcelablePlease.class.getSimpleName());
        return false;
      }

      // Ok, its a valid class
      return true;
    } else {
      ProcessorMessage.error(element,
          "Element %s is annotated with @%s but is not a class. Only Classes are supported",
          element.getSimpleName(), ParcelablePlease.class.getSimpleName());
      return false;
    }
  }


public static boolean isTypeOf(TypeMirror type, Class<?> clazz) {
    return type.toString().equals(clazz.getCanonicalName());
  }

public static boolean isTypeOf ( TypeMirror type , Class < ? > clazz ) { return type . toString ( ) . equals ( clazz . getCanonicalName ( ) ) ; }


public static Class<?> isTypeOf(TypeMirror type, List<Class<?>> classList) {

    for (Class<?> c : classList) {
      if (isTypeOf(type, c)) {
        return c;
      }
    }

    return null;
  }

public static Class < ? > isTypeOf ( TypeMirror type , List < Class < ? > > classList ) { for ( Class < ? > c : classList ) { if ( isTypeOf ( type , c ) ) { return c ; } } return null ; }

Returns the class this element is part of


public static String getPackageName(Elements elementUtils, TypeElement type) throws IOException {
    PackageElement pkg = elementUtils.getPackageOf(type);
    if (!pkg.isUnnamed()) {
      return pkg.getQualifiedName().toString();
    } else {
      return ""; // Default package
    }
  }

public
static
String
getPackageName
(
Elements
elementUtils
,
TypeElement
type
)
throws
IOException
{
PackageElement
pkg
=
elementUtils
.
getPackageOf
(
type
)
;
if
(
!
pkg
.
isUnnamed
(
)
)
{
return
pkg
.
getQualifiedName
(
)
.
toString
(
)
;
}
else
{
return
""
;
// Default package
}
}

Get the Package name

@throws IOException


public static String getBinaryName(Elements elementUtils, TypeElement type) throws IOException {
    String packageName = getPackageName(elementUtils, type);
    String qualifiedName = type.getQualifiedName().toString();
    if (packageName.length() > 0) {
      return packageName + '.' + qualifiedName.substring(packageName.length() + 1).replace('.', '$');
    } else {
      return qualifiedName.replace('.', '$');
    }
  }

public static String getBinaryName ( Elements elementUtils , TypeElement type ) throws IOException { String packageName = getPackageName ( elementUtils , type ) ; String qualifiedName = type . getQualifiedName ( ) . toString ( ) ; if ( packageName . length ( ) > 0 ) { return packageName + ' ' + qualifiedName . substring ( packageName . length ( ) + 1 ) . replace ( ' ' , ' ' ) ; } else { return qualifiedName . replace ( ' ' , ' ' ) ; } }

Get the qualified name of a class. Also respects innner classes

@param elementUtils Elements
@param type TypeElement
@return The qualified name of the class represented by the passed type element
@throws IOException

Get the qualified name of a class . Also respects innner classes


private void generateWriteToParcel(JavaWriter jw, String originClass,
      List<ParcelableField> fields) throws IOException {

    jw.beginMethod("void", "writeToParcel", EnumSet.of(Modifier.PUBLIC, Modifier.STATIC),
        originClass, PARAM_SOURCE, "Parcel", PARAM_PARCEL, "int", PARAM_FLAGS);

    for (ParcelableField field : fields) {
      FieldCodeGen gen = field.getCodeGenerator();

      if (gen == null) { // Already checked before, but let's check it again
        ProcessorMessage.error(field.getElement(),
            "The field %s is not Parcelable or of unsupported type. Use a @%s",
            field.getFieldName(),
            Bagger.class.getSimpleName() + " to provide your own serialisation mechanism");

        throw new IOException("Unparcelable Field " + field.getFieldName());
      }

      jw.emitEmptyLine();
      gen.generateWriteToParcel(field, jw);
    }

    jw.endMethod();
  }

Generate the writeToParcel method

@throws IOException


private boolean isPublicClass(DeclaredType type) {
    Element element = type.asElement();

    return element.getModifiers().contains(javax.lang.model.element.Modifier.PUBLIC);
  }

private boolean isPublicClass ( DeclaredType type ) { Element element = type . asElement ( ) ; return element . getModifiers ( ) . contains ( javax . lang . model . element . Modifier . PUBLIC ) ; }


private boolean hasPublicEmptyConstructor(DeclaredType type) {
    Element element = type.asElement();

    List<? extends Element> containing = element.getEnclosedElements();

    for (Element e : containing) {
      if (e.getKind() == ElementKind.CONSTRUCTOR) {
        ExecutableElement c = (ExecutableElement) e;

        if ((c.getParameters() == null || c.getParameters().isEmpty()) && c.getModifiers()
            .contains(javax.lang.model.element.Modifier.PUBLIC)) {
          return true;
        }
      }
    }

    return false;
  }

private boolean hasPublicEmptyConstructor ( DeclaredType type ) { Element element = type . asElement ( ) ; List < ? extends Element > containing = element . getEnclosedElements ( ) ; for ( Element e : containing ) { if ( e . getKind ( ) == ElementKind . CONSTRUCTOR ) { ExecutableElement c = ( ExecutableElement ) e ; if ( ( c . getParameters ( ) == null || c . getParameters ( ) . isEmpty ( ) ) && c . getModifiers ( ) . contains ( javax . lang . model . element . Modifier . PUBLIC ) ) { return true ; } } } return false ; }

Checks if an public empty constructor is available


public static double determinant3x3(
    final double r0c0,
    final double r0c1,
    final double r0c2,
    final double r1c0,
    final double r1c1,
    final double r1c2,
    final double r2c0,
    final double r2c1,
    final double r2c2)
  {
    double sum = 0.0;
    sum += r0c0 * ((r1c1 * r2c2) - (r1c2 * r2c1));
    sum -= r0c1 * ((r1c0 * r2c2) - (r1c2 * r2c0));
    sum += r0c2 * ((r1c0 * r2c1) - (r1c1 * r2c0));
    return sum;
  }

public static double determinant3x3 ( final double r0c0 , final double r0c1 , final double r0c2 , final double r1c0 , final double r1c1 , final double r1c2 , final double r2c0 , final double r2c1 , final double r2c2 ) { double sum = 0.0 ; sum += r0c0 * ( ( r1c1 * r2c2 ) - ( r1c2 * r2c1 ) ) ; sum -= r0c1 * ( ( r1c0 * r2c2 ) - ( r1c2 * r2c0 ) ) ; sum += r0c2 * ( ( r1c0 * r2c1 ) - ( r1c1 * r2c0 ) ) ; return sum ; }

Calculate the determinant of the given 3x3 matrix values.

@param r0c0 The value at row 0 column 0
@param r0c1 The value at row 0 column 1
@param r0c2 The value at row 0 column 2
@param r1c0 The value at row 1 column 0
@param r1c1 The value at row 1 column 1
@param r1c2 The value at row 1 column 2
@param r2c0 The value at row 2 column 0
@param r2c1 The value at row 2 column 1
@param r2c2 The value at row 2 column 2

@return The determinant

Calculate the determinant of the given 3x3 matrix values .


public R findBy(ClassFileScanConfiguration scanConfig, SearchCriteria criteria) {
		scanConfig = scanConfig.createCopy();
		criteria = criteria.createCopy();
		C context = createContext(scanConfig, criteria);
		criteria.init(this.classHelper, context.pathMemoryClassLoader, this.memberFinder, this.pathHelper);
		scanConfig.init();
		fileSystemHelper.scan(
			scanConfig.toScanConfiguration(context, this)
		);
		Collection<String> skippedClassesNames = context.getSkippedClassNames();
		if (!skippedClassesNames.isEmpty()) {
			logWarn("Skipped classes count: {}", skippedClassesNames.size());
		}
		return resultSupplier.apply(context);
	}

public
R
findBy
(
ClassFileScanConfiguration
scanConfig
,
SearchCriteria
criteria
)
{
scanConfig
=
scanConfig
.
createCopy
(
)
;
criteria
=
criteria
.
createCopy
(
)
;
C
context
=
createContext
(
scanConfig
,
criteria
)
;
criteria
.
init
(
this
.
classHelper
,
context
.
pathMemoryClassLoader
,
this
.
memberFinder
,
this
.
pathHelper
)
;
scanConfig
.
init
(
)
;
fileSystemHelper
.
scan
(
scanConfig
.
toScanConfiguration
(
context
,
this
)
)
;
Collection
<
String
>
skippedClassesNames
=
context
.
getSkippedClassNames
(
)
;
if
(
!
skippedClassesNames
.
isEmpty
(
)
)
{
logWarn
(
"Skipped classes count: {}"
,
skippedClassesNames
.
size
(
)
)
;
}
return
resultSupplier
.
apply
(
context
)
;
}


public static Generator<Matrix4x4D> createOrthogonal()
  {
    return () -> {
      final SecureRandom rng = new SecureRandom();

      final double r0c0 = 1.0;
      final double r0c1 = 0.0;
      final double r0c2 = 0.0;
      final double r0c3 = rng.nextDouble();

      final double r1c0 = 0.0;
      final double r1c1 = 1.0;
      final double r1c2 = 0.0;
      final double r1c3 = rng.nextDouble();

      final double r2c0 = 0.0;
      final double r2c1 = 0.0;
      final double r2c2 = 1.0;
      final double r2c3 = rng.nextDouble();

      final double r3c0 = 0.0;
      final double r3c1 = 0.0;
      final double r3c2 = 0.0;
      final double r3c3 = 1.0;

      return Matrix4x4D.of(
        r0c0, r0c1, r0c2, r0c3,
        r1c0, r1c1, r1c2, r1c3,
        r2c0, r2c1, r2c2, r2c3,
        r3c0, r3c1, r3c2, r3c3);
    };
  }

public static Generator < Matrix4x4D > createOrthogonal ( ) { return ( ) -> { final SecureRandom rng = new SecureRandom ( ) ; final double r0c0 = 1.0 ; final double r0c1 = 0.0 ; final double r0c2 = 0.0 ; final double r0c3 = rng . nextDouble ( ) ; final double r1c0 = 0.0 ; final double r1c1 = 1.0 ; final double r1c2 = 0.0 ; final double r1c3 = rng . nextDouble ( ) ; final double r2c0 = 0.0 ; final double r2c1 = 0.0 ; final double r2c2 = 1.0 ; final double r2c3 = rng . nextDouble ( ) ; final double r3c0 = 0.0 ; final double r3c1 = 0.0 ; final double r3c2 = 0.0 ; final double r3c3 = 1.0 ; return Matrix4x4D . of ( r0c0 , r0c1 , r0c2 , r0c3 , r1c0 , r1c1 , r1c2 , r1c3 , r2c0 , r2c1 , r2c2 , r2c3 , r3c0 , r3c1 , r3c2 , r3c3 ) ; } ; }

Create a generator initialized with a default component generator that only
produces orthogonal matrices.

@return A generator

Create a generator initialized with a default component generator that only produces orthogonal matrices .


@SuppressWarnings("unchecked")
    public static List<byte[]> getBinaryMultiBulkReply(byte[] input) {
        return (List<byte[]>) RedisProtocol.read(
                new RedisInputStream(new ByteArrayInputStream(input)));
    }

@ SuppressWarnings ( "unchecked" ) public static List < byte [ ] > getBinaryMultiBulkReply ( byte [ ] input ) { return ( List < byte [ ] > ) RedisProtocol . read ( new RedisInputStream ( new ByteArrayInputStream ( input ) ) ) ; }

Gets the binary multi bulk reply.

@return the binary multi bulk reply


private Set<Tuple> getBinaryTupledSet() {
        List<byte[]> membersWithScores = client.getBinaryMultiBulkReply();
        Set<Tuple> set = new LinkedHashSet<Tuple>();
        if (membersWithScores == null) {
            return set;
        }

        Iterator<byte[]> iterator = membersWithScores.iterator();
        if (iterator == null) {
            return set;
        }

        while (iterator.hasNext()) {
            set.add(new Tuple(iterator.next(), Double.valueOf(SafeEncoder.encode(iterator.next()))));
        }
        return set;
    }

private Set < Tuple > getBinaryTupledSet ( ) { List < byte [ ] > membersWithScores = client . getBinaryMultiBulkReply ( ) ; Set < Tuple > set = new LinkedHashSet < Tuple > ( ) ; if ( membersWithScores == null ) { return set ; } Iterator < byte [ ] > iterator = membersWithScores . iterator ( ) ; if ( iterator == null ) { return set ; } while ( iterator . hasNext ( ) ) { set . add ( new Tuple ( iterator . next ( ) , Double . valueOf ( SafeEncoder . encode ( iterator . next ( ) ) ) ) ) ; } return set ; }

Gets the binary tupled set.

@return the binary tupled set


@SuppressWarnings("unchecked")
    byte[] rawKey(Object key) {
        Assert.notNull(key, "non null key required");
        return keySerializer().serialize(key);
    }

@
SuppressWarnings
(
"unchecked"
)
byte
[
]
rawKey
(
Object
key
)
{
Assert
.
notNull
(
key
,
"non null key required"
)
;
return
keySerializer
(
)
.
serialize
(
key
)
;
}

Raw key.

@param key the key
@return the byte[]


@SuppressWarnings("unchecked")
    <HK> byte[] rawHashKey(HK hashKey) {
        Assert.notNull(hashKey, "non null hash key required");
        return hashKeySerializer().serialize(hashKey);
    }

@
SuppressWarnings
(
"unchecked"
)
<
HK
>
byte
[
]
rawHashKey
(
HK
hashKey
)
{
Assert
.
notNull
(
hashKey
,
"non null hash key required"
)
;
return
hashKeySerializer
(
)
.
serialize
(
hashKey
)
;
}

Raw hash key.

@param <HK>    the generic type
@param hashKey the hash key
@return the byte[]


@SuppressWarnings("unchecked")
    Set<TypedTuple<V>> deserializeTupleValues(Set<Tuple> rawValues) {
        Set<TypedTuple<V>> set = new LinkedHashSet<TypedTuple<V>>(rawValues.size());
        for (Tuple rawValue : rawValues) {
            set.add(new DefaultTypedTuple(valueSerializer().deserialize(rawValue.getValue()), rawValue.getScore()));
        }
        return set;
    }

@ SuppressWarnings ( "unchecked" ) Set < TypedTuple < V > > deserializeTupleValues ( Set < Tuple > rawValues ) { Set < TypedTuple < V >> set = new LinkedHashSet < TypedTuple < V > > ( rawValues . size ( ) ) ; for ( Tuple rawValue : rawValues ) { set . add ( new DefaultTypedTuple ( valueSerializer ( ) . deserialize ( rawValue . getValue ( ) ) , rawValue . getScore ( ) ) ) ; } return set ; }

Deserialize tuple values.

@param rawValues the raw values
@return the sets the


@SuppressWarnings("unchecked")
    <T> Set<T> deserializeHashKeys(Set<byte[]> rawKeys) {
        return SerializationUtils.deserialize(rawKeys, hashKeySerializer());
    }

@ SuppressWarnings ( "unchecked" ) < T > Set < T > deserializeHashKeys ( Set < byte [ ] > rawKeys ) { return SerializationUtils . deserialize ( rawKeys , hashKeySerializer ( ) ) ; }

Deserialize hash keys.

@param <T>     the generic type
@param rawKeys the raw keys
@return the sets the


@SuppressWarnings("unchecked")
    <T> List<T> deserializeHashValues(List<byte[]> rawValues) {
        return SerializationUtils.deserialize(rawValues, hashValueSerializer());
    }

@ SuppressWarnings ( "unchecked" ) < T > List < T > deserializeHashValues ( List < byte [ ] > rawValues ) { return SerializationUtils . deserialize ( rawValues , hashValueSerializer ( ) ) ; }

Deserialize hash values.

@param <T>       the generic type
@param rawValues the raw values
@return the list


@SuppressWarnings("unchecked")
    <HK, HV> Map<HK, HV> deserializeHashMap(Map<byte[], byte[]> entries) {
        // connection in pipeline/multi mode
        if (entries == null) {
            return null;
        }

        Map<HK, HV> map = new LinkedHashMap<HK, HV>(entries.size());

        for (Map.Entry<byte[], byte[]> entry : entries.entrySet()) {
            map.put((HK) deserializeHashKey(entry.getKey()), (HV) deserializeHashValue(entry.getValue()));
        }

        return map;
    }

@
SuppressWarnings
(
"unchecked"
)
<
HK
,
HV
>
Map
<
HK
,
HV
>
deserializeHashMap
(
Map
<
byte
[
]
,
byte
[
]
>
entries
)
{
// connection in pipeline/multi mode
if
(
entries
==
)
{
return
;
}
Map
<
HK
,
HV
>
map
=
new
LinkedHashMap
<
HK
,
HV
>
(
entries
.
size
(
)
)
;
for
(
Map
.
Entry
<
byte
[
]
,
byte
[
]
>
entry
:
entries
.
entrySet
(
)
)
{
map
.
put
(
(
HK
)
deserializeHashKey
(
entry
.
getKey
(
)
)
,
(
HV
)
deserializeHashValue
(
entry
.
getValue
(
)
)
)
;
}
return
map
;
}

Deserialize hash map.

@param <HK>    the generic type
@param <HV>    the generic type
@param entries the entries
@return the map


<HK, HV> Map<HK, List<HV>> deserializeHashList(Map<byte[], List<byte[]>> entries) {
        // connection in pipeline/multi mode
        if (entries == null) {
            return null;
        }

        Map<HK, List<HV>> map = new LinkedHashMap<HK, List<HV>>(entries.size());

        for (Map.Entry<byte[], List<byte[]>> entry : entries.entrySet()) {
            map.put((HK) deserializeHashKey(entry.getKey()), (List<HV>) deserializeHashValues(entry.getValue()));
        }

        return map;
    }

<
HK
,
HV
>
Map
<
HK
,
List
<
HV
>
>
deserializeHashList
(
Map
<
byte
[
]
,
List
<
byte
[
]
>
>
entries
)
{
// connection in pipeline/multi mode
if
(
entries
==
)
{
return
;
}
Map
<
HK
,
List
<
HV
>
>
map
=
new
LinkedHashMap
<
HK
,
List
<
HV
>
>
(
entries
.
size
(
)
)
;
for
(
Map
.
Entry
<
byte
[
]
,
List
<
byte
[
]
>
>
entry
:
entries
.
entrySet
(
)
)
{
map
.
put
(
(
HK
)
deserializeHashKey
(
entry
.
getKey
(
)
)
,
(
List
<
HV
>
)
deserializeHashValues
(
entry
.
getValue
(
)
)
)
;
}
return
map
;
}

Deserialize hash list.

@param <HK>    the generic type
@param <HV>    the generic type
@param entries the entries
@return the map


<HK, HV> Map<HK, Set<HV>> deserializeHashSet(Map<byte[], Set<byte[]>> entries) {
        // connection in pipeline/multi mode
        if (entries == null) {
            return null;
        }

        Map<HK, Set<HV>> map = new LinkedHashMap<HK, Set<HV>>(entries.size());

        for (Map.Entry<byte[], Set<byte[]>> entry : entries.entrySet()) {
            map.put((HK) deserializeHashKey(entry.getKey()), (Set<HV>) deserializeValues(entry.getValue()));
        }

        return map;
    }

<
HK
,
HV
>
Map
<
HK
,
Set
<
HV
>
>
deserializeHashSet
(
Map
<
byte
[
]
,
Set
<
byte
[
]
>
>
entries
)
{
// connection in pipeline/multi mode
if
(
entries
==
)
{
return
;
}
Map
<
HK
,
Set
<
HV
>
>
map
=
new
LinkedHashMap
<
HK
,
Set
<
HV
>
>
(
entries
.
size
(
)
)
;
for
(
Map
.
Entry
<
byte
[
]
,
Set
<
byte
[
]
>
>
entry
:
entries
.
entrySet
(
)
)
{
map
.
put
(
(
HK
)
deserializeHashKey
(
entry
.
getKey
(
)
)
,
(
Set
<
HV
>
)
deserializeValues
(
entry
.
getValue
(
)
)
)
;
}
return
map
;
}

Deserialize hash set.

@param <HK>    the generic type
@param <HV>    the generic type
@param entries the entries
@return the map


public static List<GatewayAddress> asListFromDomain(final String domainAddress) {
        if (domainAddress == null) {
            throw new IllegalArgumentException("domain address must not be null");
        }

        GatewayAddress domain = new GatewayAddress(0, domainAddress);
        InetAddress[] addresses;
        try {
            addresses = InetAddress.getAllByName(domain.getHost());
        } catch (Exception e) {
            throw new IllegalArgumentException("invalid domain '" + domain + "' " + e.getMessage());
        }

        List<GatewayAddress> list = new ArrayList<GatewayAddress>();
        int id = 1;
        for (InetAddress address : addresses) {
            list.add(new GatewayAddress(id++, address.getHostAddress(), domain.getPort()));
        }

        return list;
    }

public
static
List
<
GatewayAddress
>
asListFromDomain
(
final
String
domainAddress
)
{
if
(
domainAddress
==
)
{
throw
new
IllegalArgumentException
(
"domain address must not be null"
)
;
}
GatewayAddress
domain
=
new
GatewayAddress
(
0
,
domainAddress
)
;
InetAddress
[
]
addresses
;
try
{
addresses
=
InetAddress
.
getAllByName
(
domain
.
getHost
(
)
)
;
}
catch
(
Exception
e
)
{
throw
new
IllegalArgumentException
(
"invalid domain '"
+
domain
+
"' "
+
e
.
getMessage
(
)
)
;
}
List
<
GatewayAddress
>
list
=
new
ArrayList
<
GatewayAddress
>
(
)
;
int
id
=
1
;
for
(
InetAddress
address
:
addresses
)
{
list
.
add
(
new
GatewayAddress
(
id
++
,
address
.
getHostAddress
(
)
,
domain
.
getPort
(
)
)
)
;
}
return
list
;
}

As list from domain.

@param domainAddress the domain address
@return the list


public static String parseHost(final String address) {
        int ep = address.indexOf(":");
        if (ep == -1 || ep == 0) {
            throw new IllegalArgumentException("invalid address '" + address + "'");
        }
        return address.substring(0, ep).trim();
    }

public
static
String
parseHost
(
final
String
address
)
{
int
ep
=
address
.
indexOf
(
":"
)
;
if
(
ep
==
1
||
ep
==
0
)
{
throw
new
IllegalArgumentException
(
"invalid address '"
+
address
+
"'"
)
;
}
return
address
.
substring
(
0
,
ep
)
.
trim
(
)
;
}

Parses the host.

@param address the address
@return the string