Merge changes I4ba34cab,Ifb7baa1d,If3d41c14,I165c6710,I78ab48d8, ...

* changes:
  Inline is{Integer,Double,Symbol,List,...} with instanceof
  Expand statistics feature to cover all vm stats
  Apply reduction limit during evaluation
  Remove incorrect copyright header from Google
  Move user stream IO setup to common PrologControl
  Apply Gerrit-style formatting settings for Eclipse
diff --git a/.classpath b/.classpath
index 40c5bcb..25bbe3b 100644
--- a/.classpath
+++ b/.classpath
@@ -3,5 +3,10 @@
 	<classpathentry kind="src" path="java"/>
 	<classpathentry kind="lib" path="buck-out/gen/lib__builtin__output/builtin.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+	<classpathentry kind="src" path=".apt_generated">
+		<attributes>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="output" path="buck-out/eclipse/classes"/>
 </classpath>
diff --git a/.gitignore b/.gitignore
index 30a487e..c49fa0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 /.settings
+/.apt_generated
 /buck-out
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index e7c056c..fb4c690 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,74 +1,434 @@
-#Tue May 31 14:42:38 PDT 2011
 eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.compliance=1.7
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=ignore
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
-org.eclipse.jdt.core.compiler.problem.comparingIdentical=ignore
-org.eclipse.jdt.core.compiler.problem.deadCode=ignore
-org.eclipse.jdt.core.compiler.problem.deprecation=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
 org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
-org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
-org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=ignore
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=ignore
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=ignore
-org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
 org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
 org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
 org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
-org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
 org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
 org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
-org.eclipse.jdt.core.compiler.problem.nullReference=ignore
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
 org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
 org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
-org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
 org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
 org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=ignore
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
 org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
 org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
-org.eclipse.jdt.core.compiler.problem.typeParameterHiding=ignore
-org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
 org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
-org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
 org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
 org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
 org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=ignore
-org.eclipse.jdt.core.compiler.problem.unusedLabel=ignore
-org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
 org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
 org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
 org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
-org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=ignore
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.processAnnotations=enabled
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field.count_dependent=1585|-1|1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable.count_dependent=1585|-1|1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method.count_dependent=1585|-1|1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package.count_dependent=1585|-1|1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=1040
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter.count_dependent=1040|-1|1040
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=1585
+org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type.count_dependent=1585|-1|1585
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=16
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments=16
+org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants.count_dependent=0|-1|0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_field_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_for_statement=16
+org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments=16
+org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_local_variable_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_new_anonymous_class=0
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration.count_dependent=16|-1|16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=0
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=0
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=2
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=true
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.comment_new_line_at_start_of_html_paragraph=true
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.force_if_else_statement_brace=false
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comment_prefix=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=3
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=2
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_comment_inline_tags=false
+org.eclipse.jdt.core.formatter.wrap_non_simple_local_variable_annotation=true
+org.eclipse.jdt.core.formatter.wrap_non_simple_member_annotation=true
+org.eclipse.jdt.core.formatter.wrap_non_simple_package_annotation=true
+org.eclipse.jdt.core.formatter.wrap_non_simple_parameter_annotation=false
+org.eclipse.jdt.core.formatter.wrap_non_simple_type_annotation=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.formatter.wrap_prefer_two_fragments=false
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/src/builtin/PRED_$atom_type0_2.java b/src/builtin/PRED_$atom_type0_2.java
index b74b6e0..b3e81c3 100644
--- a/src/builtin/PRED_$atom_type0_2.java
+++ b/src/builtin/PRED_$atom_type0_2.java
@@ -21,7 +21,7 @@
 	a2 = arg2;
 
 	a1 = a1.dereference();
-	if(! a1.isSymbol())
+	if(! (a1 instanceof SymbolTerm))
 	    return engine.fail();
 	type = Token.getStringType(((SymbolTerm)a1).name());
 	if(! a2.unify(new IntegerTerm(type), engine.trail)) 
diff --git a/src/builtin/PRED_$call_2.java b/src/builtin/PRED_$call_2.java
index 99d960a..7034583 100644
--- a/src/builtin/PRED_$call_2.java
+++ b/src/builtin/PRED_$call_2.java
@@ -34,13 +34,13 @@
 	Operation pred;
 
 	try {
-	    if (! a1.isSymbol())
+	    if (! (a1 instanceof SymbolTerm))
 		throw new IllegalTypeException(this, 1, "atom", a1);
-	    if (a2.isSymbol()) {
+	    if (a2 instanceof SymbolTerm) {
 		functor = ((SymbolTerm)a2).name();
 		args    = new Term[] {};
 		arity   = 0;
-	    } else if (a2.isStructure()) {
+	    } else if (a2 instanceof StructureTerm) {
 		functor = ((StructureTerm)a2).functor().name();
 		args    = ((StructureTerm)a2).args();
 		arity   = ((StructureTerm)a2).arity();
diff --git a/src/builtin/PRED_$call_closure_1.java b/src/builtin/PRED_$call_closure_1.java
index 25e1493..6371364 100644
--- a/src/builtin/PRED_$call_closure_1.java
+++ b/src/builtin/PRED_$call_closure_1.java
@@ -20,7 +20,7 @@
 	// a1 must be closure
 	a1 = arg1.dereference();
 
-	if (! a1.isClosure())
+	if (! (a1 instanceof ClosureTerm))
 	    return engine.fail();
 	code = ((ClosureTerm) a1).getCode();
 	code.cont = this.cont;
diff --git a/src/builtin/PRED_$cut_1.java b/src/builtin/PRED_$cut_1.java
index ba759e5..fe44bf8 100644
--- a/src/builtin/PRED_$cut_1.java
+++ b/src/builtin/PRED_$cut_1.java
@@ -18,7 +18,7 @@
         Term a1;
         a1 = arg1;
         a1 = a1.dereference();
-        if (! a1.isInteger()) {
+        if (! (a1 instanceof IntegerTerm)) {
             throw new IllegalTypeException("integer", a1);
         } else {
             engine.cut(((IntegerTerm) a1).intValue());
diff --git a/src/builtin/PRED_$end_exception_1.java b/src/builtin/PRED_$end_exception_1.java
index 9793c29..6e7385a 100644
--- a/src/builtin/PRED_$end_exception_1.java
+++ b/src/builtin/PRED_$end_exception_1.java
@@ -20,7 +20,7 @@
 	a1 = arg1;
 
 	a1 = a1.dereference();
-	if (! a1.isJavaObject())
+	if (! (a1 instanceof JavaObjectTerm))
 	    throw new IllegalTypeException(this, 1, "java", a1);
 	Object obj = ((JavaObjectTerm)a1).object();
 	if (! (obj instanceof PRED_$begin_exception_1))
diff --git a/src/builtin/PRED_$erase_1.java b/src/builtin/PRED_$erase_1.java
index 5b68f24..427ea41 100644
--- a/src/builtin/PRED_$erase_1.java
+++ b/src/builtin/PRED_$erase_1.java
@@ -19,7 +19,7 @@
 	int idx;
 
 	a1 = a1.dereference();
-	if (! a1.isInteger())
+	if (! (a1 instanceof IntegerTerm))
 	    throw new IllegalTypeException(this, 1, "integer", a1);
 	idx = ((IntegerTerm)a1).intValue();
 	engine.internalDB.erase(idx);
diff --git a/src/builtin/PRED_$fast_write_2.java b/src/builtin/PRED_$fast_write_2.java
index a86fa8a..d70ff3f 100644
--- a/src/builtin/PRED_$fast_write_2.java
+++ b/src/builtin/PRED_$fast_write_2.java
@@ -27,13 +27,13 @@
 
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_$fast_writeq_2.java b/src/builtin/PRED_$fast_writeq_2.java
index 7b83a69..be7deab 100644
--- a/src/builtin/PRED_$fast_writeq_2.java
+++ b/src/builtin/PRED_$fast_writeq_2.java
@@ -27,13 +27,13 @@
 
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_$get_hash_manager_1.java b/src/builtin/PRED_$get_hash_manager_1.java
index 1dbcdd7..032859c 100644
--- a/src/builtin/PRED_$get_hash_manager_1.java
+++ b/src/builtin/PRED_$get_hash_manager_1.java
@@ -19,7 +19,7 @@
         a1 = arg1;
 
 	a1 = a1.dereference();
-	if (! a1.isVariable())
+	if (! (a1 instanceof VariableTerm))
 	    throw new IllegalTypeException(this, 1, "variable", a1);
 	if (! a1.unify(new JavaObjectTerm(engine.getHashManager()), engine.trail))
 	    return engine.fail();
diff --git a/src/builtin/PRED_$get_instances_2.java b/src/builtin/PRED_$get_instances_2.java
index 464daf5..6459148 100644
--- a/src/builtin/PRED_$get_instances_2.java
+++ b/src/builtin/PRED_$get_instances_2.java
@@ -26,19 +26,19 @@
 	int idx;
 
 	a1 = a1.dereference();
-	if (a1.isNil())
+	if (Prolog.Nil.equals(a1))
 	    return engine.fail();
-	if (! a1.isList())
+	if (! (a1 instanceof ListTerm))
 	    throw new IllegalTypeException(this, 1, "list", a1);
 	Term x = Prolog.Nil;
 	Term tmp = a1;
-	while(! tmp.isNil()) {
-	    if (! tmp.isList())
+	while(! Prolog.Nil.equals(tmp)) {
+	    if (! (tmp instanceof ListTerm))
 		throw new IllegalTypeException(this, 1, "list", a1);
 	    Term car = ((ListTerm)tmp).car().dereference();
-	    if (car.isVariable())
+	    if (car instanceof VariableTerm)
 		throw new PInstantiationException(this, 1);
-	    if (! car.isInteger()) 
+	    if (! (car instanceof IntegerTerm)) 
 		throw new RepresentationException(this, 1, "integer");
 	    // car is an integer
 	    int i = ((IntegerTerm)car).intValue();
diff --git a/src/builtin/PRED_$hash_adda_3.java b/src/builtin/PRED_$hash_adda_3.java
index f915af6..8fa9068 100644
--- a/src/builtin/PRED_$hash_adda_3.java
+++ b/src/builtin/PRED_$hash_adda_3.java
@@ -31,13 +31,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_$hash_addz_3.java b/src/builtin/PRED_$hash_addz_3.java
index a43d946..600deda 100644
--- a/src/builtin/PRED_$hash_addz_3.java
+++ b/src/builtin/PRED_$hash_addz_3.java
@@ -31,13 +31,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
@@ -49,16 +49,16 @@
 	if (elem == null)
 	    elem = SYM_NIL;
 	a3 = a3.dereference();
-	if (elem.isNil()) {
+	if (Prolog.Nil.equals(elem)) {
 	    elem = new ListTerm(a3, elem);
 	} else {
 	    Term x = elem;
 	    Term y;
 	    while(true) {
-		if (! x.isList())
+		if (! (x instanceof ListTerm))
 		    throw new InternalException(this + ": the valus of " + a2 + " is not list structure");
 		y = ((ListTerm)x).cdr().dereference();
-		if (y.isNil()) {
+		if (Prolog.Nil.equals(y)) {
 		    ((ListTerm)x).setCdr(new ListTerm(a3, SYM_NIL));
 		    break;
 		}
diff --git a/src/builtin/PRED_$hash_remove_first_3.java b/src/builtin/PRED_$hash_remove_first_3.java
index 5cf03ec..7733ced 100644
--- a/src/builtin/PRED_$hash_remove_first_3.java
+++ b/src/builtin/PRED_$hash_remove_first_3.java
@@ -31,13 +31,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
@@ -46,20 +46,20 @@
 	    throw new InternalException(this + ": Hash is not HashtableOfTerm");
 	a2 = a2.dereference();
 	Term elem = ((HashtableOfTerm) hash).get(a2);
-	if (elem == null || elem.isNil())
+	if (elem == null || Prolog.Nil.equals(elem))
 	    return cont;
 	a3 = a3.dereference();
 	Term x  = elem;
 	Term x0 = Prolog.Nil;
 	Term y,z;
-	while(! x.isNil()) {
-	    if (! x.isList())
+	while(! Prolog.Nil.equals(x)) {
+	    if (! (x instanceof ListTerm))
 		throw new InternalException(this + ": the valus of " + a2 + " is not list structure");
 	    y = ((ListTerm)x).car().dereference();
 	    z = ((ListTerm)x).cdr().dereference();
 	    if (y.equals(a3)) {
-		if (z.isNil()) {
-		    if (x0.isList())
+		if (Prolog.Nil.equals(z)) {
+		    if (x0 instanceof ListTerm)
 			((ListTerm)x0).setCdr(Prolog.Nil);
 		    else 
 			elem = Prolog.Nil;
@@ -72,7 +72,7 @@
 	    x0 = x;
 	    x = z;
 	}
-	if (elem.isNil() && a2.isInteger()) {
+	if (Prolog.Nil.equals(elem) && a2 instanceof IntegerTerm) {
 	    ((HashtableOfTerm)hash).remove(a2);
 	    //	    System.out.println("################ key " + a2 + " is removed");
 	} else {
diff --git a/src/builtin/PRED_$insert_2.java b/src/builtin/PRED_$insert_2.java
index 47186cb..25d9525 100644
--- a/src/builtin/PRED_$insert_2.java
+++ b/src/builtin/PRED_$insert_2.java
@@ -22,7 +22,7 @@
 	int idx;
 
 	a2 = a2.dereference();
-	if (! a2.isVariable())
+	if (! (a2 instanceof VariableTerm))
 	    throw new IllegalTypeException(this, 2, "variable", a2);
 	a1 = a1.dereference();
 	idx = engine.internalDB.insert(a1);
diff --git a/src/builtin/PRED_$read_token0_3.java b/src/builtin/PRED_$read_token0_3.java
index f5d473e..68ac170 100644
--- a/src/builtin/PRED_$read_token0_3.java
+++ b/src/builtin/PRED_$read_token0_3.java
@@ -37,13 +37,13 @@
 
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_$set_prolog_impl_flag_2.java b/src/builtin/PRED_$set_prolog_impl_flag_2.java
index 77b2142..1bb354b 100644
--- a/src/builtin/PRED_$set_prolog_impl_flag_2.java
+++ b/src/builtin/PRED_$set_prolog_impl_flag_2.java
@@ -24,7 +24,7 @@
 	a2 = a2.dereference();
 
 	if (a1.equals(DEBUG)) {
-	    if (! a2.isSymbol())
+	    if (! (a2 instanceof SymbolTerm))
 		return engine.fail();
 	    engine.setDebug(((SymbolTerm)a2).name());
 	} else {
diff --git a/src/builtin/PRED_$statistics_2.java b/src/builtin/PRED_$statistics_2.java
index 6d8b75c..897ebf7 100644
--- a/src/builtin/PRED_$statistics_2.java
+++ b/src/builtin/PRED_$statistics_2.java
@@ -28,12 +28,12 @@
 	Term result = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+    engine.requireFeature(Prolog.Feature.STATISTICS, this, a1);
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (! a1.isSymbol()) {
+	} else if (! (a1 instanceof SymbolTerm)) {
 	    throw new IllegalTypeException(this, 1, "atom", a1);
 	} else if (a1.equals(SYM_RUNTIME)) {
-	    engine.requireFeature(Prolog.Feature.STATISTICS_RUNTIME, this, a1);
 	    long val1, val2;
 	    Term start, previous;
 	    val1 = System.currentTimeMillis() - engine.getStartRuntime();
@@ -61,7 +61,7 @@
 	} else {
 	    return engine.fail();
 	}
-	if (! a2.unify(result, engine.trail)) 
+	if (! a2.unify(result, engine.trail))
 	    return engine.fail();
 	return cont;
     }
diff --git a/src/builtin/PRED_$univ_2.java b/src/builtin/PRED_$univ_2.java
index 5bad417..f6918cf 100644
--- a/src/builtin/PRED_$univ_2.java
+++ b/src/builtin/PRED_$univ_2.java
@@ -30,16 +30,16 @@
         a2 = arg2;
 
 	a1 = a1.dereference();
-	if (a1.isSymbol() || a1.isNumber() || a1.isJavaObject() || a1.isClosure()) {
+	if (a1 instanceof SymbolTerm || ((a1 instanceof IntegerTerm) || (a1 instanceof DoubleTerm)) || a1 instanceof JavaObjectTerm || a1 instanceof ClosureTerm) {
 	    if (! a2.unify(new ListTerm(a1, SYM_NIL), engine.trail))
 		return engine.fail();
-	} else if (a1.isList()) {
+	} else if (a1 instanceof ListTerm) {
 	    Term t = new ListTerm(((ListTerm)a1).cdr(), SYM_NIL);
 	    t = new ListTerm(((ListTerm)a1).car(), t);
 	    t = new ListTerm(SYM_DOT, t);
 	    if (! a2.unify(t, engine.trail))
 		return engine.fail();
-	} else if (a1.isStructure()) {
+	} else if (a1 instanceof StructureTerm) {
 	    SymbolTerm sym = SymbolTerm.create(((StructureTerm)a1).functor().name());
 	    Term[] args = ((StructureTerm)a1).args();
 	    Term t = SYM_NIL;
@@ -47,20 +47,20 @@
 		t = new ListTerm(args[i-1], t);
 	    if (! a2.unify(new ListTerm(sym, t), engine.trail))
 		return engine.fail();
-	} else if (a1.isVariable()) {
+	} else if (a1 instanceof VariableTerm) {
 	    a2 = a2.dereference();
-	    if (a2.isVariable())
+	    if (a2 instanceof VariableTerm)
 		throw new PInstantiationException(this, 2);
 	    else if (a2.equals(SYM_NIL))
 		throw new IllegalDomainException(this, 2, "non_empty_list", a2);
-	    else if (! a2.isList())
+	    else if (! (a2 instanceof ListTerm))
 		throw new IllegalTypeException(this, 2, "list", a2);
 	    Term head = ((ListTerm)a2).car().dereference();
 	    Term tail = ((ListTerm)a2).cdr().dereference();
-	    if (head.isVariable())
+	    if (head instanceof VariableTerm)
 		throw new PInstantiationException(this, 2);
 	    if (tail.equals(SYM_NIL)) {
-		if (head.isSymbol() || head.isNumber() || head.isJavaObject() || head.isClosure()) {
+		if (head instanceof SymbolTerm || ((head instanceof IntegerTerm) || (head instanceof DoubleTerm)) || head instanceof JavaObjectTerm || head instanceof ClosureTerm) {
 		    if (! a1.unify(head, engine.trail))
 			return engine.fail();
 		    return cont;
@@ -68,13 +68,13 @@
 		    throw new IllegalTypeException(this, 2, "atomic", head);
 		}
 	    }
-	    if (! head.isSymbol())
+	    if (! (head instanceof SymbolTerm))
 		throw new IllegalTypeException(this, 2, "atom", head);
 	    Term x = tail;
 	    while(! x.equals(SYM_NIL)) {
-		if (x.isVariable())
+		if (x instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! x.isList())
+		if (! (x instanceof ListTerm))
 		    throw new IllegalTypeException(this, 2, "list", a2);
 		x = ((ListTerm)x).cdr().dereference();
 	    }
diff --git a/src/builtin/PRED_$write_toString_2.java b/src/builtin/PRED_$write_toString_2.java
index d45fff2..7c0dc18 100644
--- a/src/builtin/PRED_$write_toString_2.java
+++ b/src/builtin/PRED_$write_toString_2.java
@@ -28,13 +28,13 @@
 
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
@@ -42,7 +42,7 @@
 	if (! (stream instanceof PrintWriter))
 	    throw new PermissionException(this, "output", "stream", a1, "");
 	a2 = a2.dereference(); 
-	if (! a2.isJavaObject())
+	if (! (a2 instanceof JavaObjectTerm))
 	    throw new IllegalTypeException(this, 2, "java", a2);
 	// print java
 	((PrintWriter) stream).print(((JavaObjectTerm)a2).object().toString());
diff --git a/src/builtin/PRED_arg_3.java b/src/builtin/PRED_arg_3.java
index ddcdb22..1e472bc 100644
--- a/src/builtin/PRED_arg_3.java
+++ b/src/builtin/PRED_arg_3.java
@@ -28,20 +28,20 @@
 	int arity, argNo;
 
 	a1 = a1.dereference();
-	if(a1.isVariable())
+	if(a1 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 1);
-	else if(! a1.isInteger())
+	else if(! (a1 instanceof IntegerTerm))
 	    throw new IllegalTypeException(this, 1, "integer", a1);
 	a2 = a2.dereference();
-	if (a2.isList()) {
+	if (a2 instanceof ListTerm) {
 	    args = new Term[2];
 	    args[0] = ((ListTerm)a2).car();
 	    args[1] = ((ListTerm)a2).cdr();
 	    arity = 2;
-	} else if (a2.isStructure()) {
+	} else if (a2 instanceof StructureTerm) {
 	    args =  ((StructureTerm)a2).args();
 	    arity = ((StructureTerm)a2).arity();
-	} else if (a2.isVariable()) {
+	} else if (a2 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 2);
 	} else {
 	    throw new IllegalTypeException(this, 2, "compound", a2);
diff --git a/src/builtin/PRED_atom_chars_2.java b/src/builtin/PRED_atom_chars_2.java
index ad34f50..e971f40 100644
--- a/src/builtin/PRED_atom_chars_2.java
+++ b/src/builtin/PRED_atom_chars_2.java
@@ -23,27 +23,27 @@
 
 	a1 = a1.dereference();
 	a2 = a2.dereference();
-	if (a1.isVariable()) { // atom_chars(-Atom, +CharList)
-	    if (a2.isNil()) {
+	if (a1 instanceof VariableTerm) { // atom_chars(-Atom, +CharList)
+	    if (Prolog.Nil.equals(a2)) {
 		if (! a1.unify(SymbolTerm.intern(""), engine.trail))
 		    return engine.fail();
 		return cont;
-	    } else if (a2.isVariable()) {
+	    } else if (a2 instanceof VariableTerm) {
 		throw new PInstantiationException(this, 2);
-	    } else if (! a2.isList()) {
+	    } else if (! (a2 instanceof ListTerm)) {
 		throw new IllegalTypeException(this, 2, "list", a2);
 	    }
 	    StringBuffer sb = new StringBuffer();
 	    Term x = a2;
-	    while(! x.isNil()) {
-		if (x.isVariable())
+	    while(! Prolog.Nil.equals(x)) {
+		if (x instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! x.isList())
+		if (! (x instanceof ListTerm))
 		    throw new IllegalTypeException(this, 2, "list", a2);
 		Term car = ((ListTerm)x).car().dereference();
-		if (car.isVariable())
+		if (car instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! car.isSymbol() || ((SymbolTerm)car).name().length() != 1)
+		if (! (car instanceof SymbolTerm) || ((SymbolTerm)car).name().length() != 1)
 		    throw new IllegalTypeException(this, 2, "character", a2);
 		sb.append(((SymbolTerm)car).name());
 		x = ((ListTerm)x).cdr().dereference();
@@ -51,8 +51,8 @@
 	    if (! a1.unify(SymbolTerm.create(sb.toString()), engine.trail))
 		return engine.fail();
 	    return cont;
-	} else if (a2.isNil() || a2.isVariable() || a2.isList()) { // atom_chars(+Atom, ?CharList)
-	    if (! a1.isSymbol())
+	} else if (Prolog.Nil.equals(a2) || a2 instanceof VariableTerm || a2 instanceof ListTerm) { // atom_chars(+Atom, ?CharList)
+	    if (! (a1 instanceof SymbolTerm))
 		throw new IllegalTypeException(this, 1, "atom", a1);
 	    String s = ((SymbolTerm)a1).name();
 	    Term x = Prolog.Nil;
diff --git a/src/builtin/PRED_atom_codes_2.java b/src/builtin/PRED_atom_codes_2.java
index bbb7bb1..e369f99 100644
--- a/src/builtin/PRED_atom_codes_2.java
+++ b/src/builtin/PRED_atom_codes_2.java
@@ -24,18 +24,18 @@
 
 	a1 = a1.dereference();
 	a2 = a2.dereference();
-	if (a1.isVariable()) { // atom_codes(-Atom, +CharCodeList)
+	if (a1 instanceof VariableTerm) { // atom_codes(-Atom, +CharCodeList)
 	    StringBuffer sb = new StringBuffer();
 	    Term x = a2;
-	    while(! x.isNil()) {
-		if (x.isVariable())
+	    while(! Prolog.Nil.equals(x)) {
+		if (x instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! x.isList())
+		if (! (x instanceof ListTerm))
 		    throw new IllegalTypeException(this, 2, "list", a2);
 		Term car = ((ListTerm)x).car().dereference();
-		if (car.isVariable())
+		if (car instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! car.isInteger()) 
+		if (! (car instanceof IntegerTerm)) 
 		    throw new RepresentationException(this, 2, "character_code");
 		// car is an integer
 		int i = ((IntegerTerm)car).intValue();
@@ -48,7 +48,7 @@
 		return engine.fail();
 	    return cont;
 	} else { // atom_codes(+Atom, ?CharCodeList)
-	    if (! a1.isSymbol())
+	    if (! (a1 instanceof SymbolTerm))
 		throw new IllegalTypeException(this, 1, "atom", a1);
 	    char[] chars = ((SymbolTerm)a1).name().toCharArray();
 	    Term x = Prolog.Nil;
diff --git a/src/builtin/PRED_atom_concat_3.java b/src/builtin/PRED_atom_concat_3.java
index 0e1ebda..8879cb8 100644
--- a/src/builtin/PRED_atom_concat_3.java
+++ b/src/builtin/PRED_atom_concat_3.java
@@ -26,7 +26,7 @@
         a3 = arg3;
 
 	a3 = a3.dereference();
-	if (a3.isSymbol()) {
+	if (a3 instanceof SymbolTerm) {
 	    String str3 = ((SymbolTerm)a3).name();
 	    int endIndex = str3.length();
 	    Term t = Prolog.Nil;
@@ -36,19 +36,19 @@
 		t = new ListTerm(new StructureTerm(AC_2, args), t);
 	    }
 	    return new PRED_$member_in_reverse_2(new StructureTerm(AC_2, a1, a2), t, cont);
-	} else if (! a3.isVariable()) {
+	} else if (! (a3 instanceof VariableTerm)) {
 	    throw new IllegalTypeException(this, 3, "atom", a3);
 	}
 	// a3 is a variable
 	a1 = a1.dereference();
 	a2 = a2.dereference();
-	if (a1.isVariable())
+	if (a1 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 1);
-	if (a2.isVariable())
+	if (a2 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 2);
-	if (! a1.isSymbol())
+	if (! (a1 instanceof SymbolTerm))
 	    throw new IllegalTypeException(this, 1, "integer", a1);
-	if (! a2.isSymbol())
+	if (! (a2 instanceof SymbolTerm))
 	    throw new IllegalTypeException(this, 2, "integer", a2);
 	String str3 = ((SymbolTerm) a1).name().concat(((SymbolTerm) a2).name());
 	if (! a3.unify(SymbolTerm.create(str3), engine.trail))
diff --git a/src/builtin/PRED_atom_length_2.java b/src/builtin/PRED_atom_length_2.java
index 4a45e28..60f9924 100644
--- a/src/builtin/PRED_atom_length_2.java
+++ b/src/builtin/PRED_atom_length_2.java
@@ -26,15 +26,15 @@
 	a1 = a1.dereference();
 	a2 = a2.dereference();
 
-	if (a1.isVariable())
+	if (a1 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 1);
-	if (! a1.isSymbol())
+	if (! (a1 instanceof SymbolTerm))
 	    throw new IllegalTypeException(this, 1, "atom", a1);
 	length = ((SymbolTerm)a1).name().length();
-	if (a2.isVariable()) {
+	if (a2 instanceof VariableTerm) {
 	    if (! a2.unify(new IntegerTerm(length), engine.trail))
 		return engine.fail();
-	} else if (a2.isInteger()) {
+	} else if (a2 instanceof IntegerTerm) {
 	    int n = ((IntegerTerm)a2).intValue();
 	    if (n < 0)
 		throw new IllegalDomainException(this, 2, "not_less_than_zero", a2);
diff --git a/src/builtin/PRED_char_code_2.java b/src/builtin/PRED_char_code_2.java
index a441b02..677d3be 100644
--- a/src/builtin/PRED_char_code_2.java
+++ b/src/builtin/PRED_char_code_2.java
@@ -24,10 +24,10 @@
 
 	a1 = a1.dereference();
 	a2 = a2.dereference();
-	if (a1.isVariable()) { // char_code(-Char, +CharCode)
-	    if (a2.isVariable()) {
+	if (a1 instanceof VariableTerm) { // char_code(-Char, +CharCode)
+	    if (a2 instanceof VariableTerm) {
 		throw new PInstantiationException(this, 2);
-	    } else if (! a2.isInteger()) {
+	    } else if (! (a2 instanceof IntegerTerm)) {
 		throw new IllegalTypeException(this, 2, "integer", a2);
 	    }
 	    int i = ((IntegerTerm)a2).intValue();
@@ -35,7 +35,7 @@
 		throw new RepresentationException(this, 2, "character_code");
 	    if (! a1.unify(SymbolTerm.create((char)i), engine.trail))
 		return engine.fail();
-	} else if (a1.isSymbol()) { // char_code(+Char, ?CharCode)
+	} else if (a1 instanceof SymbolTerm) { // char_code(+Char, ?CharCode)
 	    String s = ((SymbolTerm)a1).name();
 	    if (s.length() != 1)
 		throw new IllegalTypeException(this, 1, "character", a1);
diff --git a/src/builtin/PRED_close_2.java b/src/builtin/PRED_close_2.java
index 9f9af56..eef0418 100644
--- a/src/builtin/PRED_close_2.java
+++ b/src/builtin/PRED_close_2.java
@@ -18,6 +18,7 @@
 import com.googlecode.prolog_cafe.lang.StructureTerm;
 import com.googlecode.prolog_cafe.lang.SymbolTerm;
 import com.googlecode.prolog_cafe.lang.Term;
+import com.googlecode.prolog_cafe.lang.VariableTerm;
 /**
  * <code>close/2</code><br>
  * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
@@ -49,15 +50,15 @@
 	// close options
 	a2 = a2.dereference();
 	Term tmp = a2;
-	while (! tmp.isNil()) {
-	    if (tmp.isVariable())
+	while (! Prolog.Nil.equals(tmp)) {
+	    if (tmp instanceof VariableTerm)
 		throw new PInstantiationException(this, 2);
-	    if (! tmp.isList())
+	    if (! (tmp instanceof ListTerm))
 		throw new IllegalTypeException(this, 2, "list", a2);
 	    Term car = ((ListTerm) tmp).car().dereference();
-	    if (car.isVariable())
+	    if (car instanceof VariableTerm)
 		throw new PInstantiationException(this, 2);
-	    if (car.isStructure()) {
+	    if (car instanceof StructureTerm) {
 		SymbolTerm functor = ((StructureTerm) car).functor();
 		Term[] args = ((StructureTerm) car).args();
 		if (functor.equals(SYM_FORCE_1)) {
@@ -78,13 +79,13 @@
 	}
 	//stream
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
@@ -109,14 +110,14 @@
 	}
 	// delete associated entries from the stream manager
 	HashtableOfTerm streamManager = engine.getStreamManager();
-	if (a1.isSymbol()) {
+	if (a1 instanceof SymbolTerm) {
 	    streamManager.remove(engine.getStreamManager().get(a1));
 	    streamManager.remove(a1);
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    Term tmp2 = streamManager.get(a1);
-	    while (! tmp2.isNil()) {
+	    while (! Prolog.Nil.equals(tmp2)) {
 		Term car = ((ListTerm) tmp2).car().dereference();
-		if (car.isStructure()) {
+		if (car instanceof StructureTerm) {
 		    SymbolTerm functor = ((StructureTerm) car).functor();
 		    Term[] args = ((StructureTerm) car).args();
 		    if (functor.equals(SYM_ALIAS_1)) {
diff --git a/src/builtin/PRED_flush_output_1.java b/src/builtin/PRED_flush_output_1.java
index 41c7909..d248069 100644
--- a/src/builtin/PRED_flush_output_1.java
+++ b/src/builtin/PRED_flush_output_1.java
@@ -24,13 +24,13 @@
 	Object stream = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_functor_3.java b/src/builtin/PRED_functor_3.java
index 55fd722..0ec8ca0 100644
--- a/src/builtin/PRED_functor_3.java
+++ b/src/builtin/PRED_functor_3.java
@@ -28,16 +28,16 @@
 
 	// functor(?X,+Y,+Z)
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    a2 = a2.dereference();
-	    if (a2.isVariable())
+	    if (a2 instanceof VariableTerm)
 		throw new PInstantiationException(this, 2);
-	    if (!a2.isSymbol() &&  !a2.isNumber() && !a2.isJavaObject() && !a2.isClosure())
+	    if (!(a2 instanceof SymbolTerm) &&  !((a2 instanceof IntegerTerm) || (a2 instanceof DoubleTerm)) && !(a2 instanceof JavaObjectTerm) && !(a2 instanceof ClosureTerm))
 		throw new IllegalTypeException(this, 2, "atomic", a2);
 	    a3 = a3.dereference();
-	    if (a3.isVariable())
+	    if (a3 instanceof VariableTerm)
 		throw new PInstantiationException(this, 3);
-	    if (! a3.isInteger())
+	    if (! (a3 instanceof IntegerTerm))
 		throw new IllegalTypeException(this, 3, "integer", a3);
 	    int n = ((IntegerTerm)a3).intValue();
 	    if (n < 0)
@@ -47,7 +47,7 @@
 		    return engine.fail();
 		return cont;
 	    }
-	    if (! a2.isSymbol())
+	    if (! (a2 instanceof SymbolTerm))
 		throw new IllegalTypeException(this, 2, "atom", a2);
 	    if (n == 2  &&  a2.equals(SYM_DOT)) {
 		Term t = new ListTerm(new VariableTerm(engine), new VariableTerm(engine));
@@ -66,13 +66,13 @@
 	// functor(+X,?Y,?Z)
 	Term functor;
 	IntegerTerm arity;
-	if (a1.isSymbol() || a1.isNumber() || a1.isJavaObject() || a1.isClosure()) {
+	if (a1 instanceof SymbolTerm || ((a1 instanceof IntegerTerm) || (a1 instanceof DoubleTerm)) || a1 instanceof JavaObjectTerm || a1 instanceof ClosureTerm) {
 	    functor = a1;
 	    arity   = new IntegerTerm(0);
-	} else if (a1.isList()) {
+	} else if (a1 instanceof ListTerm) {
 	    functor = SYM_DOT;
 	    arity   = new IntegerTerm(2);
-	} else if (a1.isStructure()) {
+	} else if (a1 instanceof StructureTerm) {
 	    functor = SymbolTerm.create(((StructureTerm)a1).name());
 	    arity   = new IntegerTerm(((StructureTerm)a1).arity());
 	} else {
diff --git a/src/builtin/PRED_get_2.java b/src/builtin/PRED_get_2.java
index 6ebcd2f..2939324 100644
--- a/src/builtin/PRED_get_2.java
+++ b/src/builtin/PRED_get_2.java
@@ -32,8 +32,8 @@
 
 	// Char
 	a2 = a2.dereference(); 
-	if (! a2.isVariable()) {
-	    if (! a2.isInteger())
+	if (! (a2 instanceof VariableTerm)) {
+	    if (! (a2 instanceof IntegerTerm))
 		throw new IllegalTypeException(this, 2, "integer", a2);
 	    int n = ((IntegerTerm)a2).intValue();
 	    if (n != -1 && ! Character.isDefined(n))
@@ -41,13 +41,13 @@
 	}
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_get_char_2.java b/src/builtin/PRED_get_char_2.java
index 538d756..88bc3e1 100644
--- a/src/builtin/PRED_get_char_2.java
+++ b/src/builtin/PRED_get_char_2.java
@@ -24,7 +24,7 @@
     }
 
     boolean inCharacter(Term t) {
-	if (! t.isSymbol())
+	if (! (t instanceof SymbolTerm))
 	    return false;
 	if (t.equals(SYM_EOF))
 	    return true;
@@ -40,17 +40,17 @@
 
 	// Char
 	a2 = a2.dereference(); 
-	if (! a2.isVariable() && ! inCharacter(a2))
+	if (! (a2 instanceof VariableTerm) && ! inCharacter(a2))
 	    throw new IllegalTypeException(this, 2, "in_character", a2);
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_halt_1.java b/src/builtin/PRED_halt_1.java
index da0f691..827f1c3 100644
--- a/src/builtin/PRED_halt_1.java
+++ b/src/builtin/PRED_halt_1.java
@@ -20,9 +20,9 @@
         a1 = arg1;
 
 	a1 = a1.dereference();
-	if (a1.isVariable())
+	if (a1 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 1);
-	if (! a1.isInteger())
+	if (! (a1 instanceof IntegerTerm))
 	    throw new IllegalTypeException(this, 1, "integer", a1);
 	engine.halt = 1 + ((IntegerTerm)a1).intValue();
         return cont;
diff --git a/src/builtin/PRED_hash_clear_1.java b/src/builtin/PRED_hash_clear_1.java
index 5c7b437..09f815a 100644
--- a/src/builtin/PRED_hash_clear_1.java
+++ b/src/builtin/PRED_hash_clear_1.java
@@ -25,13 +25,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_hash_contains_key_2.java b/src/builtin/PRED_hash_contains_key_2.java
index dad9c71..0bbe0c2 100644
--- a/src/builtin/PRED_hash_contains_key_2.java
+++ b/src/builtin/PRED_hash_contains_key_2.java
@@ -26,13 +26,13 @@
 
 	Object hash = null;
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_hash_get_3.java b/src/builtin/PRED_hash_get_3.java
index 1e01a2f..6830e28 100644
--- a/src/builtin/PRED_hash_get_3.java
+++ b/src/builtin/PRED_hash_get_3.java
@@ -29,13 +29,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_hash_is_empty_1.java b/src/builtin/PRED_hash_is_empty_1.java
index 6ba3c8f..2075963 100644
--- a/src/builtin/PRED_hash_is_empty_1.java
+++ b/src/builtin/PRED_hash_is_empty_1.java
@@ -25,13 +25,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_hash_keys_2.java b/src/builtin/PRED_hash_keys_2.java
index dfb34c6..dc0a73b 100644
--- a/src/builtin/PRED_hash_keys_2.java
+++ b/src/builtin/PRED_hash_keys_2.java
@@ -28,13 +28,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_hash_put_3.java b/src/builtin/PRED_hash_put_3.java
index 51d73c9..f5377e8 100644
--- a/src/builtin/PRED_hash_put_3.java
+++ b/src/builtin/PRED_hash_put_3.java
@@ -29,13 +29,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_hash_remove_2.java b/src/builtin/PRED_hash_remove_2.java
index 7ab2613..8bb7284 100644
--- a/src/builtin/PRED_hash_remove_2.java
+++ b/src/builtin/PRED_hash_remove_2.java
@@ -27,13 +27,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
diff --git a/src/builtin/PRED_hash_size_2.java b/src/builtin/PRED_hash_size_2.java
index e1fe6c1..ed1623a 100644
--- a/src/builtin/PRED_hash_size_2.java
+++ b/src/builtin/PRED_hash_size_2.java
@@ -28,13 +28,13 @@
 	Object hash = null;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getHashManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "hash", a1, "");
 	    hash = ((JavaObjectTerm) engine.getHashManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    hash = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "hash_or_alias", a1);
@@ -42,7 +42,7 @@
 	if (! (hash instanceof HashtableOfTerm))
 	    throw new InternalException(this + ": Hash is not HashtableOfTerm");
 	a2 = a2.dereference();
-	if (! a2.isVariable() && ! a2.isInteger())
+	if (! (a2 instanceof VariableTerm) && ! (a2 instanceof IntegerTerm))
 	    throw new IllegalTypeException(this, 1, "integer", a2);
 	if (! a2.unify(new IntegerTerm(((HashtableOfTerm)hash).size()), engine.trail))
 	    return engine.fail();
diff --git a/src/builtin/PRED_keysort_2.java b/src/builtin/PRED_keysort_2.java
index c2ab4fe..6ff42f5 100644
--- a/src/builtin/PRED_keysort_2.java
+++ b/src/builtin/PRED_keysort_2.java
@@ -30,25 +30,25 @@
 	Term[] list;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
 	} else if (a1.equals(Prolog.Nil)) {
 	    if (! a2.unify(Prolog.Nil, engine.trail))
 		return engine.fail();
 	    return cont;
-	} else if (! a1.isList()) {
+	} else if (! (a1 instanceof ListTerm)) {
 	    throw new IllegalTypeException(this, 1, "list", a1);
 	}
 	len = ((ListTerm)a1).length();
 	list = new Term[len];
 	tmp = a1;
 	for (int i=0; i<len; i++) {
-	    if (! tmp.isList())
+	    if (! (tmp instanceof ListTerm))
 		throw new IllegalTypeException(this, 1, "list", a1);
 	    list[i] = ((ListTerm)tmp).car().dereference();
-	    if (list[i].isVariable())
+	    if (list[i] instanceof VariableTerm)
 		throw new PInstantiationException(this, 1);
-	    if (! list[i].isStructure())
+	    if (! (list[i] instanceof StructureTerm))
 		throw new IllegalTypeException(this, 1, "key_value_pair", a1);
 	    if (! ((StructureTerm) list[i]).functor().equals(SYM_HYPHEN_2))
 		throw new IllegalTypeException(this, 1, "key_value_pair", a1);
diff --git a/src/builtin/PRED_new_hash_2.java b/src/builtin/PRED_new_hash_2.java
index 467458f..9ac2923 100644
--- a/src/builtin/PRED_new_hash_2.java
+++ b/src/builtin/PRED_new_hash_2.java
@@ -26,33 +26,33 @@
         a2 = arg2;
 
 	a1 = a1.dereference();
-	if (! a1.isVariable())
+	if (! (a1 instanceof VariableTerm))
 	    throw new IllegalTypeException(this, 1, "variable", a1);
 	Term newHash = new JavaObjectTerm(new HashtableOfTerm());
 	a2 = a2.dereference();
-	if (a2.isNil()) {
+	if (Prolog.Nil.equals(a2)) {
 	    if (! a1.unify(newHash, engine.trail))
 		return engine.fail();
 	    return cont;
-	} else if (! a2.isList()) {
+	} else if (! (a2 instanceof ListTerm)) {
 	    throw new IllegalTypeException(this, 2, "list", a2);
 	}
 	// a2 is list
 	Term tmp = a2;
-	while (! tmp.isNil()) {
-	    if (tmp.isVariable())
+	while (! Prolog.Nil.equals(tmp)) {
+	    if (tmp instanceof VariableTerm)
 		throw new PInstantiationException(this, 2);
-	    if (! tmp.isList())
+	    if (! (tmp instanceof ListTerm))
 		throw new IllegalTypeException(this, 2, "list", a2);
 	    Term car = ((ListTerm) tmp).car().dereference();
-	    if (car.isVariable())
+	    if (car instanceof VariableTerm)
 		throw new PInstantiationException(this, 2);
-	    if (car.isStructure()) {
+	    if (car instanceof StructureTerm) {
 		SymbolTerm functor = ((StructureTerm) car).functor();
 		Term[] args = ((StructureTerm) car).args();
 		if (functor.equals(SYM_ALIAS_1)) {
 		    Term alias = args[0].dereference();
-		    if (! alias.isSymbol())
+		    if (! (alias instanceof SymbolTerm))
 			throw new IllegalDomainException(this, 2, "hash_option", car);
 		    else {
 			if (engine.getHashManager().containsKey(alias))
diff --git a/src/builtin/PRED_number_chars_2.java b/src/builtin/PRED_number_chars_2.java
index 56700c4..14526c7 100644
--- a/src/builtin/PRED_number_chars_2.java
+++ b/src/builtin/PRED_number_chars_2.java
@@ -24,25 +24,25 @@
 
 	a1 = a1.dereference();
 	a2 = a2.dereference();
-	if (a2.isNil())
+	if (Prolog.Nil.equals(a2))
 	    throw new SyntaxException(this, 2, "character_code_list", a2, "");
-	if (a1.isVariable()) { // number_chars(-Number, +CharList)
-	    if (a2.isVariable()) {
+	if (a1 instanceof VariableTerm) { // number_chars(-Number, +CharList)
+	    if (a2 instanceof VariableTerm) {
 		throw new PInstantiationException(this, 2);
-	    } else if (! a2.isList()) {
+	    } else if (! (a2 instanceof ListTerm)) {
 		throw new IllegalTypeException(this, 2, "list", a2);
 	    }
 	    StringBuffer sb = new StringBuffer();
 	    Term x = a2;
-	    while(! x.isNil()) {
-		if (x.isVariable())
+	    while(! Prolog.Nil.equals(x)) {
+		if (x instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! x.isList())
+		if (! (x instanceof ListTerm))
 		    throw new IllegalTypeException(this, 2, "list", a2);
 		Term car = ((ListTerm)x).car().dereference();
-		if (car.isVariable())
+		if (car instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! car.isSymbol() || ((SymbolTerm)car).name().length() != 1)
+		if (! (car instanceof SymbolTerm) || ((SymbolTerm)car).name().length() != 1)
 		    throw new IllegalTypeException(this, 2, "character", a2);
 		sb.append(((SymbolTerm)car).name());
 		x = ((ListTerm)x).cdr().dereference();
@@ -59,7 +59,7 @@
 	    } catch (NumberFormatException e) {
 		throw new SyntaxException(this, 2, "character_code_list", a2, "");
 	    }
-	} else if (a1.isNumber()) { // number_chars(+Number, ?CharList)
+	} else if (((a1 instanceof IntegerTerm) || (a1 instanceof DoubleTerm))) { // number_chars(+Number, ?CharList)
 	    String s = a1.toString();
 	    Term y = Prolog.Nil;
 	    for (int i=s.length(); i>0; i--) {
diff --git a/src/builtin/PRED_number_codes_2.java b/src/builtin/PRED_number_codes_2.java
index c5c6722..b87173c 100644
--- a/src/builtin/PRED_number_codes_2.java
+++ b/src/builtin/PRED_number_codes_2.java
@@ -25,20 +25,20 @@
 
 	a1 = a1.dereference();
 	a2 = a2.dereference();
-	if (a2.isNil())
+	if (Prolog.Nil.equals(a2))
 	    throw new SyntaxException(this, 2, "character_code_list", a2, "");
-	if (a1.isVariable()) { // number_codes(-Number, +CharCodeList)
+	if (a1 instanceof VariableTerm) { // number_codes(-Number, +CharCodeList)
 	    StringBuffer sb = new StringBuffer();
 	    Term x = a2;
-	    while(! x.isNil()) {
-		if (x.isVariable())
+	    while(! Prolog.Nil.equals(x)) {
+		if (x instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! x.isList())
+		if (! (x instanceof ListTerm))
 		    throw new IllegalTypeException(this, 2, "list", a2);
 		Term car = ((ListTerm)x).car().dereference();
-		if (car.isVariable())
+		if (car instanceof VariableTerm)
 		    throw new PInstantiationException(this, 2);
-		if (! car.isInteger()) 
+		if (! (car instanceof IntegerTerm)) 
 		    throw new RepresentationException(this, 2, "character_code");
 		// car is an integer
 		int i = ((IntegerTerm)car).intValue();
@@ -59,7 +59,7 @@
 	    } catch (NumberFormatException e) {
 		throw new SyntaxException(this, 2, "character_code_list", a2, "");
 	    }
-	} else if (a1.isNumber()) { // number_codes(+Number, ?CharCodeList)
+	} else if (((a1 instanceof IntegerTerm) || (a1 instanceof DoubleTerm))) { // number_codes(+Number, ?CharCodeList)
 	    char[] chars = a1.toString().toCharArray();
 	    Term y = Prolog.Nil;
 	    for (int i=chars.length; i>0; i--) {
diff --git a/src/builtin/PRED_open_4.java b/src/builtin/PRED_open_4.java
index 3d1b25d..d502060 100644
--- a/src/builtin/PRED_open_4.java
+++ b/src/builtin/PRED_open_4.java
@@ -48,20 +48,20 @@
 
 	// stream
 	a3 = a3.dereference();
-	if (! a3.isVariable())
+	if (! (a3 instanceof VariableTerm))
 	    throw new IllegalTypeException(this, 3, "variable", a3);
 	// source_sink
 	a1 = a1.dereference();
-	if (a1.isVariable())
+	if (a1 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 1);
-	if (! a1.isSymbol())
+	if (! (a1 instanceof SymbolTerm))
 	    throw new IllegalDomainException(this, 1, "source_sink", a1);
 	file = new File(((SymbolTerm) a1).name());
 	// io_mode
 	a2 = a2.dereference();
-	if (a2.isVariable())
+	if (a2 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 2);
-	if (! a2.isSymbol()) 
+	if (! (a2 instanceof SymbolTerm)) 
 	    throw new IllegalTypeException(this, 2, "atom", a2);
 	try {
 	    if (a2.equals(SYM_READ)) {
@@ -92,20 +92,20 @@
 	// stream_options
 	a4 = a4.dereference();
 	Term tmp = a4;
-	while (! tmp.isNil()) {
-	    if (tmp.isVariable())
+	while (! Prolog.Nil.equals(tmp)) {
+	    if (tmp instanceof VariableTerm)
 		throw new PInstantiationException(this, 4);
-	    if (! tmp.isList())
+	    if (! (tmp instanceof ListTerm))
 		throw new IllegalTypeException(this, 4, "list", a4);
 	    Term car = ((ListTerm) tmp).car().dereference();
-	    if (car.isVariable())
+	    if (car instanceof VariableTerm)
 		throw new PInstantiationException(this, 4);
-	    if (car.isStructure()) {
+	    if (car instanceof StructureTerm) {
 		SymbolTerm functor = ((StructureTerm) car).functor();
 		Term[] args = ((StructureTerm) car).args();
 		if (functor.equals(SYM_ALIAS_1)) {
 		    alias = args[0].dereference();
-		    if (! alias.isSymbol())
+		    if (! (alias instanceof SymbolTerm))
 			throw new IllegalDomainException(this, 4, "stream_option", car);
 		    if (engine.getStreamManager().containsKey(alias))
 			throw new PermissionException(this, "open", "source_sink", car, "");
diff --git a/src/builtin/PRED_put_char_2.java b/src/builtin/PRED_put_char_2.java
index 950dc29..6c4dba3 100644
--- a/src/builtin/PRED_put_char_2.java
+++ b/src/builtin/PRED_put_char_2.java
@@ -31,19 +31,19 @@
 
 	// Char
 	a2 = a2.dereference(); 
-	if (a2.isVariable())
+	if (a2 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 2);
-	if (! a2.isSymbol())
+	if (! (a2 instanceof SymbolTerm))
 	    throw new IllegalTypeException(this, 2, "character", a2);
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_put_code_2.java b/src/builtin/PRED_put_code_2.java
index 4897883..2de0a59 100644
--- a/src/builtin/PRED_put_code_2.java
+++ b/src/builtin/PRED_put_code_2.java
@@ -30,19 +30,19 @@
 
 	// Char
 	a2 = a2.dereference(); 
-	if (a2.isVariable())
+	if (a2 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 2);
-	if (! a2.isInteger())
+	if (! (a2 instanceof IntegerTerm))
 	    throw new IllegalTypeException(this, 2, "integer", a2);
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_raise_exception_1.java b/src/builtin/PRED_raise_exception_1.java
index 7bd37e7..54bca01 100644
--- a/src/builtin/PRED_raise_exception_1.java
+++ b/src/builtin/PRED_raise_exception_1.java
@@ -20,7 +20,7 @@
 	a1 = arg1;
 
 	a1 = a1.dereference();
-	if (a1.isVariable())
+	if (a1 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 1);
 	throw new TermException(a1);
     }
diff --git a/src/builtin/PRED_read_line_2.java b/src/builtin/PRED_read_line_2.java
index bc2d2cd..5d53724 100644
--- a/src/builtin/PRED_read_line_2.java
+++ b/src/builtin/PRED_read_line_2.java
@@ -32,13 +32,13 @@
 
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/builtin/PRED_regex_compile_2.java b/src/builtin/PRED_regex_compile_2.java
index 26b7509..147e5e5 100644
--- a/src/builtin/PRED_regex_compile_2.java
+++ b/src/builtin/PRED_regex_compile_2.java
@@ -7,6 +7,7 @@
 import com.googlecode.prolog_cafe.lang.Prolog;
 import com.googlecode.prolog_cafe.lang.SymbolTerm;
 import com.googlecode.prolog_cafe.lang.Term;
+import com.googlecode.prolog_cafe.lang.VariableTerm;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -31,10 +32,10 @@
       Term a1 = arg1.dereference();
       Term a2 = arg2.dereference();
 
-      if (a1.isVariable()) {
+      if (a1 instanceof VariableTerm) {
         throw new PInstantiationException(this, 1);
       }
-      if (!a1.isSymbol()) {
+      if (!(a1 instanceof SymbolTerm)) {
         throw new IllegalTypeException(this, 1, "atom", a1);
       }
       Pattern pattern = Pattern.compile(a1.name(), Pattern.MULTILINE);
diff --git a/src/builtin/PRED_regex_match_3.java b/src/builtin/PRED_regex_match_3.java
index a96779a..cf5fcd2 100644
--- a/src/builtin/PRED_regex_match_3.java
+++ b/src/builtin/PRED_regex_match_3.java
@@ -8,6 +8,7 @@
 import com.googlecode.prolog_cafe.lang.Prolog;
 import com.googlecode.prolog_cafe.lang.SymbolTerm;
 import com.googlecode.prolog_cafe.lang.Term;
+import com.googlecode.prolog_cafe.lang.VariableTerm;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -38,15 +39,15 @@
       Term a1 = arg1.dereference();
       Term a2 = arg2.dereference();
 
-      if (a1.isVariable()) {
+      if (a1 instanceof VariableTerm) {
         throw new PInstantiationException(this, 1);
       }
       Pattern pattern = (Pattern)((JavaObjectTerm)a1).object();
 
-      if (a2.isVariable()) {
+      if (a2 instanceof VariableTerm) {
         throw new PInstantiationException(this, 1);
       }
-      if (!a2.isSymbol()) {
+      if (!(a2 instanceof SymbolTerm)) {
         throw new IllegalTypeException(this, 1, "atom", a2);
       }
       Matcher matcher = pattern.matcher(a2.name());
@@ -104,4 +105,4 @@
     }
     return list;
   }
-}
\ No newline at end of file
+}
diff --git a/src/builtin/PRED_sort_2.java b/src/builtin/PRED_sort_2.java
index 8325b97..be71d37 100644
--- a/src/builtin/PRED_sort_2.java
+++ b/src/builtin/PRED_sort_2.java
@@ -27,20 +27,20 @@
 	Term[] list;
 
 	a1 = a1.dereference();
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
 	} else if (a1.equals(Prolog.Nil)) {
 	    if (! a2.unify(Prolog.Nil, engine.trail))
 		return engine.fail();
 	    return cont;
-	} else if (! a1.isList()) {
+	} else if (! (a1 instanceof ListTerm)) {
 	    throw new IllegalTypeException(this, 1, "list", a1);
 	}
 	len = ((ListTerm)a1).length();
 	list = new Term[len];
 	tmp = a1;
 	for (int i=0; i<len; i++) {
-	    if (! tmp.isList())
+	    if (! (tmp instanceof ListTerm))
 		throw new IllegalTypeException(this, 1, "list", a1);
 	    list[i] = ((ListTerm)tmp).car().dereference();
 	    tmp = ((ListTerm)tmp).cdr().dereference();
diff --git a/src/builtin/PRED_tab_2.java b/src/builtin/PRED_tab_2.java
index ec58a1b..f92c6df 100644
--- a/src/builtin/PRED_tab_2.java
+++ b/src/builtin/PRED_tab_2.java
@@ -30,9 +30,9 @@
 
 	// Char
 	a2 = a2.dereference(); 
-	if (a2.isVariable())
+	if (a2 instanceof VariableTerm)
 	    throw new PInstantiationException(this, 2);
-	if (! a2.isInteger()) {
+	if (! (a2 instanceof IntegerTerm)) {
 	    try {
 		a2 = Arithmetic.evaluate(a2);
 	    } catch (BuiltinException e) {
@@ -44,13 +44,13 @@
 	n = ((NumberTerm)a2).intValue();
 	// S_or_a
 	a1 = a1.dereference(); 
-	if (a1.isVariable()) {
+	if (a1 instanceof VariableTerm) {
 	    throw new PInstantiationException(this, 1);
-	} else if (a1.isSymbol()) {
+	} else if (a1 instanceof SymbolTerm) {
 	    if (! engine.getStreamManager().containsKey(a1))
 		throw new ExistenceException(this, 1, "stream", a1, "");
 	    stream = ((JavaObjectTerm) engine.getStreamManager().get(a1)).object();
-	} else if (a1.isJavaObject()) {
+	} else if (a1 instanceof JavaObjectTerm) {
 	    stream = ((JavaObjectTerm) a1).object();
 	} else {
 	    throw new IllegalDomainException(this, 1, "stream_or_alias", a1);
diff --git a/src/compiler/Compiler.java b/src/compiler/Compiler.java
index 1912022..cfc1a78 100644
--- a/src/compiler/Compiler.java
+++ b/src/compiler/Compiler.java
@@ -101,6 +101,7 @@
       pcl = new BufferingPrologControl();
       pcl.setEnabled(EnumSet.allOf(Prolog.Feature.class), true);
       pcl.setPrologClassLoader(new PrologClassLoader(Compiler.class.getClassLoader()));
+      pcl.setReductionLimit(Long.MAX_VALUE);
       options = EnumSet.noneOf(Option.class);
       enableDefaultOptions();
     }
diff --git a/src/compiler/am2j.pl b/src/compiler/am2j.pl
index 2121f86..d7a753e 100644
--- a/src/compiler/am2j.pl
+++ b/src/compiler/am2j.pl
@@ -336,7 +336,7 @@
 	write_java0(deref(Xj,Xj), In, Out),
 	% read mode
 	tab(Out, 8), 
-	write(Out, 'if ('), write_reg(Xj, Out), write(Out, '.isInteger()){'), nl(Out),
+	write(Out, 'if ('), write_reg(Xj, Out), write(Out, ' instanceof IntegerTerm){'), nl(Out),
 	tab(Out, 12), 
 	write(Out, 'if (((IntegerTerm) '), write_reg(Xj, Out), write(Out, ').intValue() != '),
 	write(Out, N), write(Out, ')'), nl(Out),
@@ -344,7 +344,7 @@
  	write(Out, 'return engine.fail();'), nl(Out),
 	% write mode
 	tab(Out, 8),
-	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, '.isVariable()){'), nl(Out),
+	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, ' instanceof VariableTerm){'), nl(Out),
 	tab(Out, 12),
 	write(Out, '((VariableTerm) '), write_reg(Xj, Out), write(Out, ').bind('),
 	write_reg(Xi, Out), write(Out, ', engine.trail);'), nl(Out),
@@ -361,7 +361,7 @@
 	write_java0(deref(Xj,Xj), In, Out),
 	% read mode
 	tab(Out, 8), 
-	write(Out, 'if ('), write_reg(Xj, Out), write(Out, '.isDouble()){'), nl(Out),
+	write(Out, 'if ('), write_reg(Xj, Out), write(Out, ' instanceof DoubleTerm)){'), nl(Out),
 	tab(Out, 12), 
 	write(Out, 'if (((DoubleTerm) '), write_reg(Xj, Out), write(Out, ').doubleValue() != '),
 	write(Out, N), write(Out, ')'), nl(Out),
@@ -369,7 +369,7 @@
  	write(Out, 'return engine.fail();'), nl(Out),
 	% write mode
 	tab(Out, 8),
-	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, '.isVariable()){'), nl(Out),
+	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, ' instanceof VariableTerm){'), nl(Out),
 	tab(Out, 12),
 	write(Out, '((VariableTerm) '), write_reg(Xj, Out), write(Out, ').bind('),
 	write_reg(Xi, Out), write(Out, ', engine.trail);'), nl(Out),
@@ -386,7 +386,7 @@
 	write_java0(deref(Xj,Xj), In, Out),
 	% read mode
 	tab(Out, 8), 
-	write(Out, 'if ('), write_reg(Xj, Out), write(Out, '.isSymbol()){'), nl(Out),
+	write(Out, 'if ('), write_reg(Xj, Out), write(Out, ' instanceof SymbolTerm){'), nl(Out),
 	tab(Out, 12), 
 	write(Out, 'if (! '), 
 	write_reg(Xj, Out), write(Out, '.equals('), write_reg(Xi, Out), 
@@ -395,7 +395,7 @@
  	write(Out, 'return engine.fail();'), nl(Out),
 	% write mode
 	tab(Out, 8),
-	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, '.isVariable()){'), nl(Out),
+	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, ' instanceof VariableTerm){'), nl(Out),
 	tab(Out, 12),
 	write(Out, '((VariableTerm) '), write_reg(Xj, Out), write(Out, ').bind('),
 	write_reg(Xi, Out), write(Out, ', engine.trail);'), nl(Out),
@@ -413,7 +413,7 @@
 	read_instructions(2, In, Us),
 	% read mode
 	tab(Out, 8), 
-	write(Out, 'if ('), write_reg(X, Out), write(Out, '.isList()){'), nl(Out),
+	write(Out, 'if ('), write_reg(X, Out), write(Out, ' instanceof ListTerm){'), nl(Out),
 	tab(Out, 12), 
 	write(Out, 'Term[] args = {((ListTerm)'), 
 	write_reg(X, Out), write(Out, ').car(), ((ListTerm)'),
@@ -421,7 +421,7 @@
 	write_unify_read(Us, 0, Out),
 	% write mode
 	tab(Out, 8),
-	write(Out, '} else if ('), write_reg(X, Out), write(Out, '.isVariable()){'), nl(Out),
+	write(Out, '} else if ('), write_reg(X, Out), write(Out, ' instanceof VariableTerm){'), nl(Out),
 	write_unify_write(Us, Rs, Out),
 	tab(Out, 12),
 	write(Out, '((VariableTerm) '), write_reg(X, Out), write(Out, ').bind(new ListTerm('),
@@ -438,7 +438,7 @@
 	read_instructions(A, In, Us),
 	% read mode
 	tab(Out, 8), 
-	write(Out, 'if ('), write_reg(Xj, Out), write(Out, '.isStructure()){'), nl(Out), %??? == F
+	write(Out, 'if ('), write_reg(Xj, Out), write(Out, ' instanceof StructureTerm){'), nl(Out), %??? == F
 	tab(Out, 12),
 	write(Out, 'if (! '), write_reg(Xi, Out),
 	write(Out, '.equals(((StructureTerm)'), write_reg(Xj, Out),
@@ -451,7 +451,7 @@
 	write_unify_read(Us, 0, Out),
 	% write mode
 	tab(Out, 8),
-	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, '.isVariable()){'), nl(Out),
+	write(Out, '} else if ('), write_reg(Xj, Out), write(Out, ' instanceof VariableTerm){'), nl(Out),
 	write_unify_write(Us, Rs, Out),
 	tab(Out, 12),
 	write(Out, 'Term[] args = {'), write_reg_args(Rs, Out), write(Out, '};'), nl(Out),
@@ -692,33 +692,39 @@
 write_inline0('$cut'(X), _, Out)       :- !,
 	write_deref_args([X], Out),
 	tab(Out, 8),
-	write(Out, 'if (! '), write_reg(X, Out), write(Out, '.isInteger()) {'), nl(Out),
-	tab(Out, 12),
-	write(Out, 'throw new IllegalTypeException("integer", '), 
-	write_reg(X, Out), write(Out, ');'), nl(Out),
-	tab(Out, 8),
-	write(Out, '} else {'), nl(Out),
+	write(Out, 'if ('), write_reg(X, Out), write(Out, ' instanceof IntegerTerm) {'), nl(Out),
 	tab(Out, 12),
 	write(Out, 'engine.cut(((IntegerTerm) '), write_reg(X, Out), 
 	write(Out, ').intValue());'), nl(Out),
 	tab(Out, 8),
+	write(Out, '} else {'), nl(Out),
+	tab(Out, 12),
+	write(Out, 'throw new IllegalTypeException("integer", '), 
+	write_reg(X, Out), write(Out, ');'), nl(Out),
+	tab(Out, 8),
 	write(Out, '}'), nl(Out).
 % Term unification
 write_inline0('$unify'(X,Y), _, Out)         :- !, write_if_fail(op('!', unify(X,Y)), [], 8, Out).
 write_inline0('$not_unifiable'(X,Y), _, Out) :- !, write_if_fail(unify(X,Y), [], 8, Out).
 % Type testing
-write_inline0(var(X), _, Out)     :- !, write_if_fail(op('!', @('isVariable'(X))), [X], 8, Out).
-write_inline0(atom(X), _, Out)    :- !, write_if_fail(op('!', @('isSymbol'(X))), [X], 8, Out).
-write_inline0(integer(X), _, Out) :- !, write_if_fail(op('!', @('isInteger'(X))), [X], 8, Out).
-write_inline0(float(X), _, Out)   :- !, write_if_fail(op('!', @('isDouble'(X))), [X], 8, Out).
-write_inline0(nonvar(X), _, Out)  :- !, write_if_fail(@('isVariable'(X)), [X], 8, Out).
-write_inline0(number(X), _, Out)  :- !, write_if_fail(op('!', @('isNumber'(X))), [X], 8, Out).
-write_inline0(java(X), _, Out)    :- !, write_if_fail(op('!', @('isJavaObject'(X))), [X], 8, Out).
-write_inline0(closure(X), _, Out) :- !, write_if_fail(op('!', @('isClosure'(X))), [X], 8, Out).
+write_inline0(var(X), _, Out)     :- !, write_if_fail(op('!', instanceof(X, 'VariableTerm')), [X], 8, Out).
+write_inline0(atom(X), _, Out)    :- !, write_if_fail(op('!', instanceof(X, 'SymbolTerm')), [X], 8, Out).
+write_inline0(integer(X), _, Out) :- !, write_if_fail(op('!', instanceof(X, 'IntegerTerm')), [X], 8, Out).
+write_inline0(float(X), _, Out)   :- !, write_if_fail(op('!', instanceof(X, 'DoubleTerm')), [X], 8, Out).
+write_inline0(nonvar(X), _, Out)  :- !, write_if_fail(instanceof(X, 'VariableTerm'), [X], 8, Out).
+write_inline0(number(X), _, Out)  :- !,
+	NI = op('!', instanceof(X, 'IntegerTerm')),
+	ND = op('!', instanceof(X, 'DoubleTerm')),
+	write_if_fail(op('&&', NI, ND) , [X], 8, Out).
+write_inline0(java(X), _, Out)    :- !, write_if_fail(op('!', instanceof(X, 'JavaObjectTerm')), [X], 8, Out).
+write_inline0(closure(X), _, Out) :- !, write_if_fail(op('!', instanceof(X, 'ClosureTerm')), [X], 8, Out).
 write_inline0(atomic(X), _, Out) :- !, 
-	write_if_fail(op('&&',op('!',@('isSymbol'(X))), op('!',@('isNumber'(X)))), [X], 8, Out).
+	NS = op('!', instanceof(X, 'SymbolTerm')),
+	NI = op('!', instanceof(X, 'IntegerTerm')),
+	ND = op('!', instanceof(X, 'DoubleTerm')),
+	write_if_fail(op('&&', NS, op('&&', NI, ND)) , [X], 8, Out).
 write_inline0(java(X,Y), _, Out) :- !, 
-	write_if_fail(op('!', @('isJavaObject'(X))), [X], 8, Out),
+	write_if_fail(op('!', instanceof(X, 'JavaObjectTerm')), [X], 8, Out),
 	EXP = #('SymbolTerm.create'(@(getName(@(getClass(@(object(cast('JavaObjectTerm',X))))))))),
 	write_if_fail(op('!', unify(Y,EXP)), [], 8, Out).
 write_inline0(ground(X), _, Out) :- !, write_if_fail(op('!', @('isGround'(X))), [X], 8, Out).
@@ -895,6 +901,12 @@
 	write(Out, Op),
 	write(Out, ' '), 
 	write_inline_exp(Exp2, 0, Out).
+write_inline_exp(instanceof(Exp,Class), Tab, Out) :- !,
+	tab(Out, Tab),
+	write(Out, '('),
+	write_inline_exp(Exp, 0, Out),
+	write(Out, ' instanceof '), write(Out, Class),
+	write(Out, ')').
 write_inline_exp(cast(Class,Exp), Tab, Out) :- !,
 	tab(Out, Tab), 
 	write(Out, '(('), write(Out, Class), write(Out, ') '), 
diff --git a/src/compiler/am2j/PRED_exists_directory_1.java b/src/compiler/am2j/PRED_exists_directory_1.java
index 87737f1..33be3c5 100644
--- a/src/compiler/am2j/PRED_exists_directory_1.java
+++ b/src/compiler/am2j/PRED_exists_directory_1.java
@@ -8,6 +8,7 @@
 import com.googlecode.prolog_cafe.lang.Prolog;
 import com.googlecode.prolog_cafe.lang.SymbolTerm;
 import com.googlecode.prolog_cafe.lang.Term;
+import com.googlecode.prolog_cafe.lang.VariableTerm;
 
 import java.io.File;
 
@@ -24,8 +25,8 @@
     engine.setB0();
 
     Term a1 = arg1.dereference();
-    if (a1.isVariable()) throw new PInstantiationException(this, 1);
-    if (!a1.isSymbol()) throw new IllegalDomainException(this, 1, "directory", a1);
+    if (a1 instanceof VariableTerm) throw new PInstantiationException(this, 1);
+    if (!(a1 instanceof SymbolTerm)) throw new IllegalDomainException(this, 1, "directory", a1);
 
     File file = new File(a1.name());
     if (file.isDirectory())
diff --git a/src/compiler/am2j/PRED_file_directory_name_2.java b/src/compiler/am2j/PRED_file_directory_name_2.java
index 46f00ba..a1e0b48 100644
--- a/src/compiler/am2j/PRED_file_directory_name_2.java
+++ b/src/compiler/am2j/PRED_file_directory_name_2.java
@@ -9,6 +9,7 @@
 import com.googlecode.prolog_cafe.lang.Prolog;
 import com.googlecode.prolog_cafe.lang.SymbolTerm;
 import com.googlecode.prolog_cafe.lang.Term;
+import com.googlecode.prolog_cafe.lang.VariableTerm;
 
 import java.io.File;
 
@@ -26,8 +27,8 @@
     engine.setB0();
 
     Term a1 = arg1.dereference();
-    if (a1.isVariable()) throw new PInstantiationException(this, 1);
-    if (!a1.isSymbol()) throw new IllegalDomainException(this, 1, "file", a1);
+    if (a1 instanceof VariableTerm) throw new PInstantiationException(this, 1);
+    if (!(a1 instanceof SymbolTerm)) throw new IllegalDomainException(this, 1, "file", a1);
 
     File file = new File(a1.name());
     File dir = file.getParentFile();
diff --git a/src/compiler/am2j/PRED_make_directory_1.java b/src/compiler/am2j/PRED_make_directory_1.java
index ed511e3..48cdced 100644
--- a/src/compiler/am2j/PRED_make_directory_1.java
+++ b/src/compiler/am2j/PRED_make_directory_1.java
@@ -9,6 +9,7 @@
 import com.googlecode.prolog_cafe.lang.Prolog;
 import com.googlecode.prolog_cafe.lang.SymbolTerm;
 import com.googlecode.prolog_cafe.lang.Term;
+import com.googlecode.prolog_cafe.lang.VariableTerm;
 
 import java.io.File;
 
@@ -25,8 +26,8 @@
     engine.setB0();
 
     Term a1 = arg1.dereference();
-    if (a1.isVariable()) throw new PInstantiationException(this, 1);
-    if (!a1.isSymbol()) throw new IllegalDomainException(this, 1, "dir", a1);
+    if (a1 instanceof VariableTerm) throw new PInstantiationException(this, 1);
+    if (!(a1 instanceof SymbolTerm)) throw new IllegalDomainException(this, 1, "dir", a1);
 
     File file = new File(((SymbolTerm) a1).name());
     if (file.mkdir())
diff --git a/src/exceptions/ReductionLimitException.java b/src/exceptions/ReductionLimitException.java
new file mode 100644
index 0000000..80ba112
--- /dev/null
+++ b/src/exceptions/ReductionLimitException.java
@@ -0,0 +1,14 @@
+package com.googlecode.prolog_cafe.exceptions;
+
+/**
+ * Thrown if a goal exceeds the configured reduction limit.
+ *
+ * @see com.googlecode.prolog_cafe.lang.PrologControl#setReductionLimit(long)
+ */
+public class ReductionLimitException extends RuntimeException {
+  private static final long serialVersionUID = 1L;
+
+  public ReductionLimitException(long limit) {
+    super(String.format("exceeded reduction limit of %d", limit));
+  }
+}
diff --git a/src/lang/Arithmetic.java b/src/lang/Arithmetic.java
index a8923f8..ec25da7 100644
--- a/src/lang/Arithmetic.java
+++ b/src/lang/Arithmetic.java
@@ -67,11 +67,11 @@
 	throws PInstantiationException,IllegalDomainException {
 	Term t = _t.dereference();
 
-	if (t.isVariable())
+	if (t instanceof VariableTerm)
 	    throw new PInstantiationException();
-	else if (t.isInteger())
+	else if (t instanceof IntegerTerm)
 	    return (IntegerTerm)t;
-	else if (t.isDouble())
+	else if (t instanceof DoubleTerm)
 	    return (DoubleTerm)t;
 	else if (t.equals(SYM_RANDOM))
 	    return new DoubleTerm(Math.random());
@@ -79,9 +79,9 @@
 	    return new DoubleTerm(Math.PI);
 	else if (t.equals(SYM_E))
 	    return new DoubleTerm(Math.E);
-	else if (t.isList())
+	else if (t instanceof ListTerm)
 	    return evaluate(((ListTerm)t).car());
-	else if (! t.isStructure()) 
+	else if (! (t instanceof StructureTerm)) 
 	    throw new IllegalDomainException("arithmetic expression", t);
 
 	SymbolTerm func = ((StructureTerm)t).functor();
diff --git a/src/lang/ChoicePointFrame.java b/src/lang/ChoicePointFrame.java
index f94dd90..8d66621 100644
--- a/src/lang/ChoicePointFrame.java
+++ b/src/lang/ChoicePointFrame.java
@@ -1,5 +1,3 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
 package com.googlecode.prolog_cafe.lang;
 
 /**
diff --git a/src/lang/ClosureTerm.java b/src/lang/ClosureTerm.java
index 8a21788..001f509 100644
--- a/src/lang/ClosureTerm.java
+++ b/src/lang/ClosureTerm.java
@@ -21,9 +21,9 @@
     /* Term */
     public boolean unify(Term t, Trail trail) {
 	//	t = t.dereference();
-	if (t.isVariable())
+	if (t instanceof VariableTerm)
 	    return ((VariableTerm)t).unify(this, trail);
-	if (! t.isClosure())
+	if (! (t instanceof ClosureTerm))
 	    return false;
 	return code.equals(((ClosureTerm)t).code);
     }
@@ -69,7 +69,7 @@
      * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
      */
     public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced
-	if (! anotherTerm.isClosure())
+	if (! (anotherTerm instanceof ClosureTerm))
 	    return AFTER;
 	if (code.equals(((ClosureTerm) anotherTerm).code))
 	    return EQUAL;
diff --git a/src/lang/DoubleTerm.java b/src/lang/DoubleTerm.java
index 62c24e8..588d815 100644
--- a/src/lang/DoubleTerm.java
+++ b/src/lang/DoubleTerm.java
@@ -35,9 +35,9 @@
 
     /* Term */
     public boolean unify(Term t, Trail trail) {
-	if (t.isVariable())
+	if (t instanceof VariableTerm)
 	    return ((VariableTerm)t).unify(this, trail);
-	if (! t.isDouble())
+	if (! (t instanceof DoubleTerm))
 	    return false;
 	return this.val == ((DoubleTerm)t).value();
     }
@@ -94,9 +94,9 @@
      * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
      */
     public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced
-	if (anotherTerm.isVariable())
+	if (anotherTerm instanceof VariableTerm)
 	    return AFTER;
-	if (! anotherTerm.isDouble())
+	if (! (anotherTerm instanceof DoubleTerm))
 	    return BEFORE;
 	return Double.compare(this.val, ((DoubleTerm)anotherTerm).value());
     }
diff --git a/src/lang/IntegerTerm.java b/src/lang/IntegerTerm.java
index 15a5e4a..e64c9b0 100644
--- a/src/lang/IntegerTerm.java
+++ b/src/lang/IntegerTerm.java
@@ -31,9 +31,9 @@
 
     /* Term */
     public boolean unify(Term t, Trail trail) {
-	if (t.isVariable())
+	if (t instanceof VariableTerm)
 	    return ((VariableTerm)t).unify(this, trail);
-	if (! t.isInteger())
+	if (! (t instanceof IntegerTerm))
 	    return false;
 	else 
 	    return this.val == ((IntegerTerm)t).value();
@@ -88,9 +88,9 @@
      * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
      */
     public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
-	if (anotherTerm.isVariable() || anotherTerm.isDouble())
+	if (anotherTerm instanceof VariableTerm || anotherTerm instanceof DoubleTerm)
 	    return AFTER;
-	if (! anotherTerm.isInteger())
+	if (! (anotherTerm instanceof IntegerTerm))
 	    return BEFORE;
 	int v = ((IntegerTerm)anotherTerm).value();
 	if (this.val == v)
@@ -108,7 +108,7 @@
     public double doubleValue() { return (double)(this.val); }
 
     public int arithCompareTo(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    return - (t.arithCompareTo(this));
 	int v = t.intValue();
 	if (this.val == v)
@@ -123,7 +123,7 @@
     public NumberTerm acos() { return new DoubleTerm(Math.acos(this.doubleValue())); }
 
     public NumberTerm add(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    return t.add(this);
 	return new IntegerTerm(this.val + t.intValue());
     }
@@ -133,7 +133,7 @@
      * <code>NumberTerm</code> is a floating point number.
      */
     public NumberTerm and(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    throw new IllegalTypeException("integer", t);
 	return new IntegerTerm(this.val & t.intValue());
     }
@@ -171,7 +171,7 @@
      * <code>NumberTerm</code> represents <coe>0</code>.
      */
     public NumberTerm intDivide(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    throw new IllegalTypeException("integer", t);
 	if (t.intValue() == 0)
 	    throw new EvaluationException("zero_divisor");
@@ -188,13 +188,13 @@
     }
 
     public NumberTerm max(NumberTerm t) {
-	if (t.isDouble()) 
+	if (t instanceof DoubleTerm) 
 	    return t.max(this);
 	return new IntegerTerm(Math.max(this.val, t.intValue()));
     }
 
     public NumberTerm min(NumberTerm t) {
-	if (t.isDouble()) 
+	if (t instanceof DoubleTerm) 
 	    return t.min(this);
 	return new IntegerTerm(Math.min(this.val, t.intValue()));
     }
@@ -206,7 +206,7 @@
      * <code>NumberTerm</code> represents <coe>0</code>.
      */
     public NumberTerm mod(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    throw new IllegalTypeException("integer", t);
 	if (t.intValue() == 0)
 	    throw new EvaluationException("zero_divisor");
@@ -214,7 +214,7 @@
     }
 
     public NumberTerm multiply(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    return t.multiply(this);
 	return new IntegerTerm(this.val * t.intValue());
     }
@@ -228,7 +228,7 @@
      * <code>NumberTerm</code> is a floating point number.
      */
     public NumberTerm or(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    throw new IllegalTypeException("integer", t);
 	return new IntegerTerm(this.val | t.intValue());
     }
@@ -244,7 +244,7 @@
      * <code>NumberTerm</code> is a floating point number.
      */
     public NumberTerm shiftLeft(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    throw new IllegalTypeException("integer", t);
 	return new IntegerTerm(this.val << t.intValue());
     }
@@ -254,7 +254,7 @@
      * <code>NumberTerm</code> is a floating point number.
      */
     public NumberTerm shiftRight(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    throw new IllegalTypeException("integer", t);
 	return new IntegerTerm(this.val >> t.intValue());
     }
@@ -274,7 +274,7 @@
     }
 
     public NumberTerm subtract(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    return new DoubleTerm(this.doubleValue() - t.doubleValue());
 	return new IntegerTerm(this.val - t.intValue());
     }
@@ -294,7 +294,7 @@
      * <code>NumberTerm</code> is a floating point number.
      */
     public NumberTerm xor(NumberTerm t) {
-	if (t.isDouble())
+	if (t instanceof DoubleTerm)
 	    throw new IllegalTypeException("integer", t);
 	return new IntegerTerm(this.val ^ t.intValue());
     }
diff --git a/src/lang/JavaObjectTerm.java b/src/lang/JavaObjectTerm.java
index eb5d782..3076f80 100644
--- a/src/lang/JavaObjectTerm.java
+++ b/src/lang/JavaObjectTerm.java
@@ -39,9 +39,9 @@
 
     /* Term */
     public boolean unify(Term t, Trail trail) {
-	if (t.isVariable())
+	if (t instanceof VariableTerm)
 	    return ((VariableTerm)t).unify(this, trail);
-	if (! t.isJavaObject())
+	if (! (t instanceof JavaObjectTerm))
 	    return false;
 	return obj.equals(((JavaObjectTerm)t).obj);
     }
@@ -101,13 +101,13 @@
      * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
      */
     public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
-	if (anotherTerm.isVariable() 
-	    || anotherTerm.isNumber() 
-	    || anotherTerm.isSymbol()
-	    || anotherTerm.isList()
-	    || anotherTerm.isStructure())
+	if (anotherTerm instanceof VariableTerm 
+	    || ((anotherTerm instanceof IntegerTerm) || (anotherTerm instanceof DoubleTerm)) 
+	    || anotherTerm instanceof SymbolTerm
+	    || anotherTerm instanceof ListTerm
+	    || anotherTerm instanceof StructureTerm)
 	    return AFTER;
-	if (! anotherTerm.isJavaObject())
+	if (! (anotherTerm instanceof JavaObjectTerm))
 	    return BEFORE;
 	if (obj.equals(((JavaObjectTerm) anotherTerm).obj))
 	    return EQUAL;
diff --git a/src/lang/ListTerm.java b/src/lang/ListTerm.java
index 942df5d..5d733db 100644
--- a/src/lang/ListTerm.java
+++ b/src/lang/ListTerm.java
@@ -78,11 +78,11 @@
     /* Term */
     public boolean unify(Term t, Trail trail) {
 	t = t.dereference();
-	if (t.isVariable()) {
+	if (t instanceof VariableTerm) {
 	    ((VariableTerm) t).bind(this, trail);
 	    return true;
 	}
-	if (! t.isList())
+	if (! (t instanceof ListTerm))
 	    return false;
 	return car.unify(((ListTerm)t).car(), trail) 
 	    && cdr.unify(((ListTerm)t).cdr(), trail);
@@ -114,11 +114,11 @@
     public Term arg(int nth) {
       Term t = this;
       int old_nth = nth;
-      while (t.isList() && 0 < nth) {
+      while (t instanceof ListTerm && 0 < nth) {
         nth--;
         t = ((ListTerm)t).cdr.dereference();
       }
-      if (t.isList())
+      if (t instanceof ListTerm)
         return ((ListTerm)t).car;
       throw new ArrayIndexOutOfBoundsException(old_nth);
     }
@@ -127,7 +127,7 @@
     public int length() {
 	int count = 0;
 	Term t = this;
-	while(t.isList()) {
+	while(t instanceof ListTerm) {
 	    count++;
 	    t = ((ListTerm)t).cdr().dereference();
 	}
@@ -143,7 +143,7 @@
     public List toJava() { 
 	List<Object> vec = new ArrayList<Object>();
 	Term t = this;
-	while(t.isList()) {
+	while(t instanceof ListTerm) {
 	    vec.add(((ListTerm)t).car().dereference().toJava());
 	    t = ((ListTerm)t).cdr().dereference();  
 	}
@@ -156,11 +156,11 @@
 	for (;;) {
 	    s += ((ListTerm)x).car.dereference().toQuotedString();
 	    x  = ((ListTerm)x).cdr.dereference();
-	    if (! x.isList())
+	    if (! (x instanceof ListTerm))
 		break;
 	    s += ",";
 	}
-	if (! x.isNil())
+	if (! Prolog.Nil.equals(x))
 	    s += "|" + x.toQuotedString();
 	s += "]";
 	return s;
@@ -199,11 +199,11 @@
 	for (;;) {
 	    s += ((ListTerm)x).car.dereference().toString();
 	    x  = ((ListTerm)x).cdr.dereference();
-	    if (! x.isList())
+	    if (! (x instanceof ListTerm))
 		break;
 	    s += ",";
 	}
-	if (! x.isNil())
+	if (! Prolog.Nil.equals(x))
 	    s += "|" + x.toString();
 	s += "]";
 	return s;
@@ -220,9 +220,9 @@
      * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
      */
     public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
-	if (anotherTerm.isVariable() || anotherTerm.isNumber() || anotherTerm.isSymbol())
+	if (anotherTerm instanceof VariableTerm || ((anotherTerm instanceof IntegerTerm) || (anotherTerm instanceof DoubleTerm)) || anotherTerm instanceof SymbolTerm)
 	    return AFTER;
-	if (anotherTerm.isStructure()) {
+	if (anotherTerm instanceof StructureTerm) {
 	    int arity = ((StructureTerm)anotherTerm).arity();
 	    if (2 != arity)
 		return (2 - arity);
@@ -231,10 +231,10 @@
 		return SYM_DOT.compareTo(functor);
 	}
 	Term[] args = new Term[2];
-	if (anotherTerm.isList()) {
+	if (anotherTerm instanceof ListTerm) {
 	    args[0] = ((ListTerm)anotherTerm).car();
 	    args[1] = ((ListTerm)anotherTerm).cdr();
-	} else if (anotherTerm.isStructure()) {
+	} else if (anotherTerm instanceof StructureTerm) {
 	    args = ((StructureTerm)anotherTerm).args();
 	} else {
 	    return BEFORE;
diff --git a/src/lang/Prolog.java b/src/lang/Prolog.java
index 4279f99..e3c059b 100644
--- a/src/lang/Prolog.java
+++ b/src/lang/Prolog.java
@@ -90,7 +90,7 @@
       IO,
 
       /** Track the running time of evaluations */
-      STATISTICS_RUNTIME;
+      STATISTICS;
     }
     protected final EnumSet<Feature> features = EnumSet.noneOf(Feature.class);
 
@@ -149,7 +149,7 @@
 	halt = 0;
 	debug = "off";
 	exception = NONE;
-	startRuntime = features.contains(Feature.STATISTICS_RUNTIME)
+	startRuntime = features.contains(Feature.STATISTICS)
 	    ? System.currentTimeMillis()
 	    : 0;
 	previousRuntime = 0;
@@ -207,17 +207,17 @@
 				    Operation str, 
 				    Operation lis) {
 	Term arg1 = r1.dereference();
-	if (arg1.isVariable())
+	if (arg1 instanceof VariableTerm)
 	    return var;
-	if (arg1.isInteger())
+	if (arg1 instanceof IntegerTerm)
 	    return Int;
-	if (arg1.isDouble())
+	if (arg1 instanceof DoubleTerm)
 	    return flo;
-	if (arg1.isSymbol())
+	if (arg1 instanceof SymbolTerm)
 	    return con;
-	if (arg1.isStructure())
+	if (arg1 instanceof StructureTerm)
 	    return str;
-	if (arg1.isList())
+	if (arg1 instanceof ListTerm)
 	    return lis;
 	return var;
     }
@@ -242,9 +242,9 @@
     public Operation switch_on_hash(HashMap<Term,Operation> hash, Operation otherwise) {
 	Term arg1 = r1.dereference();
 	Term key;
-	if (arg1.isInteger() || arg1.isDouble() || arg1.isSymbol()) {
+	if (arg1 instanceof IntegerTerm || arg1 instanceof DoubleTerm || arg1 instanceof SymbolTerm) {
 	    key = arg1;
-	} else if (arg1.isStructure()) {
+	} else if (arg1 instanceof StructureTerm) {
 	    key = ((StructureTerm) arg1).functor();
 	} else {
 	    throw new SystemException("Invalid argument in switch_on_hash");
diff --git a/src/lang/PrologControl.java b/src/lang/PrologControl.java
index b10a178..02bd6ae 100644
--- a/src/lang/PrologControl.java
+++ b/src/lang/PrologControl.java
@@ -2,7 +2,16 @@
 
 import com.googlecode.prolog_cafe.exceptions.HaltException;
 import com.googlecode.prolog_cafe.exceptions.PrologException;
+import com.googlecode.prolog_cafe.exceptions.ReductionLimitException;
 
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.PushbackReader;
 import java.util.Set;
 
 /**
@@ -24,6 +33,10 @@
     /** Holds a Prolog goal to be executed. */
     protected Operation code;
 
+    /** How many operations can be executed before exceeding cost limit. */
+    private long reductionLimit = 1 << 20;
+    private long reductionsUsed;
+
     /** Constructs a new <code>PrologControl</code>. */
     public PrologControl() {
       engine = new Prolog(this);
@@ -73,7 +86,36 @@
       engine.pcl = cl;
     }
 
-    /** Sets a goal and its arguments to this Prolog thread. 
+    /**
+     * Registers {@code user_input}, {@code user_output}, and {@code user_error}
+     * streams.
+     */
+    public void configureUserIO(InputStream in, OutputStream out,
+        OutputStream err) {
+      if (in != null) {
+        engine.streamManager.put(
+            SymbolTerm.intern("user_input"),
+            new JavaObjectTerm(new PushbackReader(
+                new BufferedReader(new InputStreamReader(in)),
+                Prolog.PUSHBACK_SIZE)));
+      }
+      if (out != null) {
+        engine.streamManager.put(
+            SymbolTerm.intern("user_output"),
+            new JavaObjectTerm(new PrintWriter(
+                new BufferedWriter(new OutputStreamWriter(out)),
+                true)));
+      }
+      if (err != null) {
+        engine.streamManager.put(
+            SymbolTerm.intern("user_error"),
+            new JavaObjectTerm(new PrintWriter(
+                new BufferedWriter(new OutputStreamWriter(err)),
+                true)));
+      }
+    }
+
+    /** Sets a goal and its arguments to this Prolog thread.
      * An initial continuation goal (a <code>Success</code> object)
      * is set to the <code>cont</code> field of goal <code>p</code> as continuation.
      */
@@ -82,7 +124,7 @@
       code = p;
     }
 
-    /** Sets a goal <code>call(t)</code> to this Prolog thread. 
+    /** Sets a goal <code>call(t)</code> to this Prolog thread.
      * An initial continuation goal (a <code>Success</code> object)
      * is set to the <code>cont</code> field of goal <code>p</code> as continuation.
      */
@@ -135,11 +177,14 @@
     protected void executePredicate() throws PrologException {
       Prolog engine = this.engine;
       Operation code = this.code;
+      long reductionsRemaining = reductionLimit;
       try {
         engine.init();
 
         do {
           if (isEngineStopped()) return;
+          if (--reductionsRemaining <= 0)
+              throw new ReductionLimitException(reductionLimit);
           code = code.exec(engine);
         } while (engine.halt == 0);
 
@@ -147,11 +192,22 @@
             throw new HaltException(engine.halt - 1);
         }
       } finally {
+        this.reductionsUsed = reductionLimit - reductionsRemaining;
         this.code = code;
         SymbolTerm.gc();
       }
     }
 
+    /** @return number of reductions used by execution. */
+    public long getReductions() {
+      return reductionsUsed;
+    }
+
+    /** Applies an upper limit on number of reductions. */
+    public void setReductionLimit(long limit) {
+      reductionLimit = Math.max(0, limit);
+    }
+
     /** @param err stack trace to print (or log). */
     public void printStackTrace(Throwable err) {
       err.printStackTrace();
diff --git a/src/lang/PrologMachineCopy.java b/src/lang/PrologMachineCopy.java
index 4dc3afe..8272c0a 100644
--- a/src/lang/PrologMachineCopy.java
+++ b/src/lang/PrologMachineCopy.java
@@ -61,7 +61,7 @@
     for (Map.Entry<Term, Term> e : src.entrySet()) {
       Term val = e.getValue().copy(engine);
 
-      if (val.isJavaObject()) {
+      if (val instanceof JavaObjectTerm) {
         JavaObjectTerm o = (JavaObjectTerm) val;
         if (o.obj instanceof HashtableOfTerm) {
           val = new JavaObjectTerm(copyDeep(engine, (HashtableOfTerm) o.obj));
@@ -78,7 +78,7 @@
     for (Map.Entry<Term, Term> e : src.entrySet()) {
       Term val = e.getValue();
 
-      if (val.isJavaObject()) {
+      if (val instanceof JavaObjectTerm) {
         JavaObjectTerm o = (JavaObjectTerm) val;
         if (o.obj instanceof HashtableOfTerm) {
           val = new JavaObjectTerm(copyShallow((HashtableOfTerm) o.obj));
diff --git a/src/lang/StructureTerm.java b/src/lang/StructureTerm.java
index dd50b01..cfd9c12 100644
--- a/src/lang/StructureTerm.java
+++ b/src/lang/StructureTerm.java
@@ -80,11 +80,11 @@
 
     public boolean unify(Term t, Trail trail) {
 	t = t.dereference();
-	if (t.isVariable()) {
+	if (t instanceof VariableTerm) {
 	    ((VariableTerm) t).bind(this, trail);
 	    return true;
 	}
-	if (! t.isStructure())
+	if (! (t instanceof StructureTerm))
 	    return false;
 	if (! functor.equals(((StructureTerm)t).functor()))
 	    return false;
@@ -179,16 +179,16 @@
 	Term[] args2;
 	int arity2, rc;
 
-	if (anotherTerm.isVariable() || anotherTerm.isNumber() || anotherTerm.isSymbol())
+	if (anotherTerm instanceof VariableTerm || ((anotherTerm instanceof IntegerTerm) || (anotherTerm instanceof DoubleTerm)) || anotherTerm instanceof SymbolTerm)
 	    return AFTER;
-	if (anotherTerm.isList()) {
+	if (anotherTerm instanceof ListTerm) {
 	    ListTerm t = (ListTerm)anotherTerm;
 	    functor2 = ListTerm.SYM_DOT;
 	    args2    = new Term[2];
 	    args2[0] = t.car();
 	    args2[1] = t.cdr();
 	    arity2   = 2;
-	} else if (anotherTerm.isStructure()) {
+	} else if (anotherTerm instanceof StructureTerm) {
 	    StructureTerm s = (StructureTerm)anotherTerm;
 	    functor2 = s.functor();
 	    args2    = s.args();
diff --git a/src/lang/SymbolTerm.java b/src/lang/SymbolTerm.java
index 1725ea6..347a103 100644
--- a/src/lang/SymbolTerm.java
+++ b/src/lang/SymbolTerm.java
@@ -182,7 +182,7 @@
     /* Term */
     public boolean unify(Term t, Trail trail) {
       t = t.dereference();
-      if (t.isVariable()) {
+      if (t instanceof VariableTerm) {
         ((VariableTerm) t).bind(this, trail);
         return true;
       }
@@ -241,9 +241,9 @@
      * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
      */
     public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
-	if (anotherTerm.isVariable() || anotherTerm.isNumber())
+	if (anotherTerm instanceof VariableTerm || ((anotherTerm instanceof IntegerTerm) || (anotherTerm instanceof DoubleTerm)))
 	    return AFTER;
-	if (! anotherTerm.isSymbol())
+	if (! (anotherTerm instanceof SymbolTerm))
 	    return BEFORE;
 	if (this == anotherTerm)
 	    return EQUAL;
diff --git a/src/lang/Term.java b/src/lang/Term.java
index 824acf0..960e156 100644
--- a/src/lang/Term.java
+++ b/src/lang/Term.java
@@ -3,7 +3,7 @@
  * The superclass of classes for term structures.
  * The subclasses of <code>Term</code> must override
  * the <code>unify</code> method.
- * 
+ *
  * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
  * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
  * @version 1.0
@@ -17,7 +17,7 @@
     /** Holds an integer value <code>-1</code>. */
     public static final int BEFORE = -1;
 
-    /** 
+    /**
      * Checks whether the argument term is unified with this one.
      * @param t the term to be unified with.
      * @param trail Trail Stack.
@@ -25,82 +25,6 @@
      */
     abstract public boolean unify(Term t, Trail trail);
 
-    /** 
-     * Check whether this term is a logical variable.
-     * @return <code>true</code> if <code>this instanceof VariableTerm</code>, 
-     * otherwise <code>false</code>.
-     * @see VariableTerm
-     */
-    public final boolean isVariable() { return this instanceof VariableTerm; }
-
-    /** 
-     * Check whether this term is an integer.
-     * @return <code>true</code> if <code>this instanceof IntegerTerm</code>, 
-     * otherwise <code>false</code>.
-     * @see IntegerTerm
-     */
-    public final boolean isInteger() { return this instanceof IntegerTerm; }
-
-    /** 
-     * Check whether this term is a float.
-     * @return <code>true</code> if <code>this instanceof DoubleTerm</code>,
-     * otherwise <code>false</code>.
-     * @see DoubleTerm
-     */
-    public final boolean isDouble() { return this instanceof DoubleTerm; }
-
-    /** 
-     * Check whether this term is a number.
-     * @return <code>true</code> if <code>this instanceof IntegerTerm || this instanceof DoubleTerm</code>, 
-     * otherwise <code>false</code>.
-     * @see IntegerTerm
-     * @see DoubleTerm
-     */
-    public final boolean isNumber() { return ((this instanceof IntegerTerm) || (this instanceof DoubleTerm)); }
-
-    /** 
-     * Check whether this term is an atom.
-     * @return <code>true</code> if <code>this instanceof SymbolTerm</code>,
-     * otherwise <code>false</code>.
-     * @see SymbolTerm
-     */
-    public final boolean isSymbol() { return this instanceof SymbolTerm; }
-
-    /** Check whether this term is an empty list. */
-    public final boolean isNil() { return Prolog.Nil.equals(this); }
-
-    /** 
-     * Check whether this term is a list structure.
-     * @return <code>true</code> if <code>this instanceof ListTerm</code>,
-     * otherwise <code>false</code>.
-     * @see ListTerm
-     */
-    public final boolean isList() { return this instanceof ListTerm; }
-
-    /** 
-     * Check whether this term is a compound term.
-     * @return <code>true</code> if <code>this instanceof StructureTerm</code>,
-     * otherwise <code>false</code>.
-     * @see StructureTerm
-     */
-    public final boolean isStructure() { return this instanceof StructureTerm; }
-
-    /** 
-     * Check whether this term is a java term.
-     * @return <code>true</code> if <code>this instanceof JavaObjectTerm</code>,
-     * otherwise <code>false</code>.
-     * @see JavaObjectTerm
-     */
-    public final boolean isJavaObject() { return this instanceof JavaObjectTerm; }
-
-    /** 
-     * Check whether this term is a closure term.
-     * @return <code>true</code> if <code>this instanceof ClosureTerm</code>,
-     * otherwise <code>false</code>.
-     * @see ClosureTerm
-     */
-    public final boolean isClosure() { return this instanceof ClosureTerm; }
-
     /** @return the name of this Term, if {@link #isStructure()}. */
     public abstract String name();
 
@@ -110,10 +34,10 @@
     /** @return get the nth argument of {@link #isStructure()} or {@link #isList()}. */
     public Term arg(int nth) { throw new ArrayIndexOutOfBoundsException(nth); }
 
-    /** 
+    /**
      * Check whether this object is convertible with the given Java class type.
      * @param type the Java class type to compare with.
-     * @return <code>true</code> if this is convertible with 
+     * @return <code>true</code> if this is convertible with
      * <code>type</code>. Otherwise <code>false</code>.
      * @see #convertible(Class, Class)
      */
@@ -125,27 +49,27 @@
     /** Returns the dereference value of this term. */
     public Term    dereference() { return this; }
 
-    /** 
+    /**
      * Check whether this term is a ground term.
      * @return <code>true</code> if ground, otherwise <code>false</code>.
      */
     public boolean isGround() { return true; }
 
-    /** 
-     * Returns a Java object that corresponds to this term 
+    /**
+     * Returns a Java object that corresponds to this term
      * if defined in <em>Prolog Cafe interoperability with Java</em>.
      * Otherwise, returns <code>this</code>.
      * @return a Java object if defined in <em>Prolog Cafe interoperability with Java</em>,
      * otherwise <code>this</code>.
      */
-    public Object  toJava() { 
+    public Object  toJava() {
 	return this;
-    } 
+    }
 
     /** Returns a quoted string representation of this term. */
     public String  toQuotedString() { return this.toString(); }
 
-    /** 
+    /**
      * Check whether there is a widening conversion from <code>from</code> to <code>to</code>.
      */
     protected static boolean convertible(Class from, Class<?> to) {
@@ -196,7 +120,7 @@
 
     /** Checks whether a given object is an instance of Prolog term. */
     public static boolean instanceOfTerm(Object obj) {
-	return obj instanceof VariableTerm || 
+	return obj instanceof VariableTerm ||
 	    obj instanceof IntegerTerm ||
 	    obj instanceof DoubleTerm ||
 	    obj instanceof SymbolTerm ||
diff --git a/src/lang/VariableTerm.java b/src/lang/VariableTerm.java
index ef28ad4..3cfd339 100644
--- a/src/lang/VariableTerm.java
+++ b/src/lang/VariableTerm.java
@@ -73,7 +73,7 @@
      * @see Trail
      */
   public void bind(Term t, Trail trail) {
-    if (t.isVariable()) {
+    if (t instanceof VariableTerm) {
       VariableTerm v = (VariableTerm) t;
       if (v.timeStamp >= this.timeStamp) {
         v.val = this;
@@ -212,7 +212,7 @@
     public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
 	if(val != this)
 	    return val.compareTo(anotherTerm);
-	if (! anotherTerm.isVariable())
+	if (! (anotherTerm instanceof VariableTerm))
 	    return BEFORE;
 	if (this == anotherTerm) 
 	    return EQUAL;
diff --git a/src/repl/BlockingPrologControl.java b/src/repl/BlockingPrologControl.java
index 829d91d..45989f4 100644
--- a/src/repl/BlockingPrologControl.java
+++ b/src/repl/BlockingPrologControl.java
@@ -119,11 +119,6 @@
     engine.init();
   }
 
-  /** Returns the stream manager. */
-  HashtableOfTerm getStreamManager() {
-    return engine.getStreamManager();
-  }
-
   /**
    * Returns <code>true</code> if the system succeeds to find a first solution
    * of the given goal, <code>false</code> otherwise.<br>
diff --git a/src/repl/PrologMain.java b/src/repl/PrologMain.java
index 4a83588..1c36e86 100644
--- a/src/repl/PrologMain.java
+++ b/src/repl/PrologMain.java
@@ -65,20 +65,7 @@
 
 	    p = new BlockingPrologControl();
 	    p.setEnabled(EnumSet.allOf(Prolog.Feature.class), true);
-		p.getStreamManager().put(
-			SymbolTerm.intern("user_input"),
-			new JavaObjectTerm(new PushbackReader(new BufferedReader(
-				new InputStreamReader(System.in)),
-				Prolog.PUSHBACK_SIZE)));
-		p.getStreamManager().put(
-			SymbolTerm.intern("user_output"),
-			new JavaObjectTerm(new PrintWriter(new BufferedWriter(
-				new OutputStreamWriter(System.out)), true)));
-		p.getStreamManager().put(
-			SymbolTerm.intern("user_error"),
-			new JavaObjectTerm(new PrintWriter(new BufferedWriter(
-				new OutputStreamWriter(System.err)), true)));
-
+	    p.configureUserIO(System.in, System.out, System.err);
 	    p.setPredicate(Prolog.BUILTIN, "initialization", arg1, arg2);
 	    for (boolean r = p.call(); r; r = p.redo()) {}
 	    System.exit(0);