public class Concept extends ConceptDescriptor {
    
    List<RefsetMembership> memberships;
    List<Description> descriptions;
    List<Relationship> relationships;
    List<Relationship> statedRelationships;
    List<Relationship> additionalRelationships;
    boolean isLeafInferred;
    boolean isLeafStated;
    String fsn;

    String semtag;
    List<String> inferredAncestors;
    List<String> statedAncestors;

    public Concept() {
    }

	public List<RefsetMembership> getMemberships() {
		return memberships;
	}

	public void setMemberships(List<RefsetMembership> memberships) {
		this.memberships = memberships;
	}

	public List<Description> getDescriptions() {
		return descriptions;
	}

	public void setDescriptions(List<Description> descriptions) {
		this.descriptions = descriptions;
	}

	public List<Relationship> getRelationships() {
		return relationships;
	}

	public void setRelationships(List<Relationship> relationships) {
		this.relationships = relationships;
	}

	public List<Relationship> getStatedRelationships() {
		return statedRelationships;
	}

	public void setStatedRelationships(List<Relationship> statedRelationships) {
		this.statedRelationships = statedRelationships;
	}

    public boolean isLeafInferred() {
        return isLeafInferred;
    }

    public void setLeafInferred(boolean isLeafInferred) {
        this.isLeafInferred = isLeafInferred;
    }

    public boolean isLeafStated() {
        return isLeafStated;
    }

    public void setLeafStated(boolean isLeafStated) {
        this.isLeafStated = isLeafStated;
    }

    public String getFsn() {
        return fsn;
    }

    public void setFsn(String fsn) {
        this.fsn = fsn;
    }

    public String getSemtag() {
        return semtag;
    }

    public void setSemtag(String semtag) {
        this.semtag = semtag;
    }

    public List<String> getInferredAncestors() {
        return inferredAncestors;
    }

    public void setInferredAncestors(List<String> inferredAncestors) {
        this.inferredAncestors = inferredAncestors;
    }

    public List<String> getStatedAncestors() {
        return statedAncestors;
    }

    public void setStatedAncestors(List<String> statedAncestors) {
        this.statedAncestors = statedAncestors;
    }

	public List<Relationship> getAdditionalRelationships() {
		return additionalRelationships;
	}

	public void setAdditionalRelationships(
			List<Relationship> additionalRelationships) {
		this.additionalRelationships = additionalRelationships;
	}
} public class ConceptDescriptor extends Component{

    String conceptId;
	String defaultTerm;
    String definitionStatus;
	int statedDescendants;
	int inferredDescendants;
	public String getConceptId() {
		return conceptId;
	}
	public void setConceptId(String conceptId) {
		this.conceptId = conceptId;
	}
	public String getDefaultTerm() {
		return defaultTerm;
	}
	public void setDefaultTerm(String defaultTerm) {
		this.defaultTerm = defaultTerm;
	}
	public String getDefinitionStatus() {
		return definitionStatus;
	}
	public void setDefinitionStatus(String definitionStatus) {
		this.definitionStatus = definitionStatus;
	}
	public int getStatedDescendants() {
		return statedDescendants;
	}
	public void setStatedDescendants(int statedDescendants) {
		this.statedDescendants = statedDescendants;
	}
	public int getInferredDescendants() {
		return inferredDescendants;
	}
	public void setInferredDescendants(int inferredDescendants) {
		this.inferredDescendants = inferredDescendants;
	}
	
} public class Description extends Component {

    String descriptionId;
    String conceptId;
    ConceptDescriptor type;
    String lang;
    String term;
    Integer length;
    ConceptDescriptor ics;
    List<LangMembership> langMemberships;
    List<RefsetMembership> refsetMemberships;

    private List<String> words;

    public Description() {
    }

    public String getDescriptionId() {
        return descriptionId;
    }

    public void setDescriptionId(String descriptionId) {
        this.descriptionId = descriptionId;
    }

    public String getConceptId() {
        return conceptId;
    }

    public void setConceptId(String conceptId) {
        this.conceptId = conceptId;
    }

    public ConceptDescriptor getType() {
        return type;
    }

    public void setType(ConceptDescriptor type) {
        this.type = type;
    }

    public String getTerm() {
        return term;
    }

    public void setTerm(String term) {
        this.term = term;
    }

    public Integer getLength() {
        return length;
    }

    public void setLength(Integer length) {
        this.length = length;
    }

    public ConceptDescriptor getIcs() {
        return ics;
    }

    public void setIcs(ConceptDescriptor ics) {
        this.ics = ics;
    }

    public List<LangMembership> getLangMemberships() {
        return langMemberships;
    }

    public void setLangMemberships(List<LangMembership> langMemberships) {
        this.langMemberships = langMemberships;
    }

    public String getLang() {
        return lang;
    }

    public void setLang(String lang) {
        this.lang = lang;
    }

	public List<RefsetMembership> getRefsetMemberships() {
		return refsetMemberships;
	}

	public void setRefsetMemberships(List<RefsetMembership> refsetMemberships) {
		this.refsetMemberships = refsetMemberships;
	}

    public List<String> getWords() {
        return words;
    }

    public void setWords(List<String> words) {
        this.words = words;
    }
} public class LangMembership extends Component {

    private String descriptionId;
	private ConceptDescriptor refset;
    private ConceptDescriptor acceptability;
    
	public ConceptDescriptor getRefset() {
		return refset;
	}

	public void setRefset(ConceptDescriptor refset) {
		this.refset = refset;
	}

	public ConceptDescriptor getAcceptability() {
		return acceptability;
	}

	public void setAcceptability(ConceptDescriptor acceptability) {
		this.acceptability = acceptability;
	}


    public LangMembership() {
        super();
    }

    public String getDescriptionId() {
        return descriptionId;
    }

    public void setDescriptionId(String descriptionId) {
        this.descriptionId = descriptionId;
    }

} public class LightDescription extends Component {

    String descriptionId;
    String conceptId;
    String type;
    String term;
    String ics;
    String lang;

    public LightDescription() {
    }

    public String getDescriptionId() {
        return descriptionId;
    }

    public void setDescriptionId(String descriptionId) {
        this.descriptionId = descriptionId;
    }

    public String getConceptId() {
        return conceptId;
    }

    public void setConceptId(String conceptId) {
        this.conceptId = conceptId;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getTerm() {
        return term;
    }

    public void setTerm(String term) {
        this.term = term;
    }

    public String getIcs() {
        return ics;
    }

    public void setIcs(String ics) {
        this.ics = ics;
    }

    public String getLang() {
        return lang;
    }

    public void setLang(String lang) {
        this.lang = lang;
    }

} public class LightLangMembership extends Component {

    private String descriptionId;
	private String refset;
    private String acceptability;
	public String getDescriptionId() {
		return descriptionId;
	}
	public void setDescriptionId(String descriptionId) {
		this.descriptionId = descriptionId;
	}
	public String getRefset() {
		return refset;
	}
	public void setRefset(String refset) {
		this.refset = refset;
	}
	public String getAcceptability() {
		return acceptability;
	}
	public void setAcceptability(String acceptability) {
		this.acceptability = acceptability;
	}
    
} public class LightRefsetMembership extends Component {
	
	public enum RefsetMembershipType {
		SIMPLEMAP("SIMPLEMAP"), ATTRIBUTE_VALUE("ATTRIBUTE_VALUE"), ASSOCIATION("ASSOCIATION"), SIMPLE_REFSET("SIMPLE_REFSET");
		private String type;
		
		RefsetMembershipType(String type) {
			this.type = type;
		}
		
		public String getType() {
			return this.type;
		}
		
		@Override
		public String toString() {
			return this.type;
		}
	}
	private String type;
	private String referencedComponentId;
	private String refset;
	private String cidValue;
	private String otherValue;
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getReferencedComponentId() {
		return referencedComponentId;
	}
	public void setReferencedComponentId(String referencedComponentId) {
		this.referencedComponentId = referencedComponentId;
	}
	public String getRefset() {
		return refset;
	}
	public void setRefset(String refset) {
		this.refset = refset;
	}
	public String getCidValue() {
		return cidValue;
	}
	public void setCidValue(String cidValue) {
		this.cidValue = cidValue;
	}
	public String getOtherValue() {
		return otherValue;
	}
	public void setOtherValue(String otherValue) {
		this.otherValue = otherValue;
	}

} public class LightRelationship extends Component {

    private String type;
    private String target;
    private String sourceId;
    private Integer groupId;
    private String charType;
    private String modifier;
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getTarget() {
		return target;
	}
	public void setTarget(String target) {
		this.target = target;
	}
	public String getSourceId() {
		return sourceId;
	}
	public void setSourceId(String sourceId) {
		this.sourceId = sourceId;
	}
	public Integer getGroupId() {
		return groupId;
	}
	public void setGroupId(Integer groupId) {
		this.groupId = groupId;
	}
	public String getCharType() {
		return charType;
	}
	public void setCharType(String charType) {
		this.charType = charType;
	}
	public String getModifier() {
		return modifier;
	}
	public void setModifier(String modifier) {
		this.modifier = modifier;
	}



} public class RefsetDescriptor extends ConceptDescriptor {

    Integer count;
    String type;

    public RefsetDescriptor(ConceptDescriptor concept, Integer count) {
        this.setDefinitionStatus(concept.getDefinitionStatus());
        this.setEffectiveTime(concept.getEffectiveTime());
        this.setCount(count);
        this.setConceptId(concept.getConceptId());
        this.setDefaultTerm(concept.getDefaultTerm());
        this.setModule(concept.getModule());
        this.setUuid(concept.getUuid());
        this.setActive(concept.isActive());
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
} public class RefsetMembership extends Component {
	
	public enum RefsetMembershipType {
		SIMPLEMAP("SIMPLEMAP"), ATTRIBUTE_VALUE("ATTRIBUTE_VALUE"), ASSOCIATION("ASSOCIATION"), SIMPLE_REFSET("SIMPLE_REFSET");
		private String type;
		
		RefsetMembershipType(String type) {
			this.type = type;
		}
		
		public String getType() {
			return this.type;
		}
		
		@Override
		public String toString() {
			return this.type;
		}
	}
	private String type;
	private String referencedComponentId;
	private ConceptDescriptor refset;
	private ConceptDescriptor cidValue;
	private String otherValue;

	public ConceptDescriptor getRefset() {
		return refset;
	}

	public void setRefset(ConceptDescriptor refset) {
		this.refset = refset;
	}

	public ConceptDescriptor getCidValue() {
		return cidValue;
	}

	public void setCidValue(ConceptDescriptor cidValue) {
		this.cidValue = cidValue;
	}


	public RefsetMembership() {
    }

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getOtherValue() {
		return otherValue;
	}

	public void setOtherValue(String otherValue) {
		this.otherValue = otherValue;
	}

	public String getReferencedComponentId() {
		return referencedComponentId;
	}

	public void setReferencedComponentId(String referencedComponentId) {
		this.referencedComponentId = referencedComponentId;
	}

} public class Relationship extends Component {

    private ConceptDescriptor type;
    private List<String> typeInferredAncestors;
    private List<String> typeStatedAncestors;
    private ConceptDescriptor target;
    private List<String> targetInferredAncestors;
    private List<String> targetStatedAncestors;
    private String sourceId;
    private Integer groupId;
    private ConceptDescriptor charType;
    private String modifier;
    private List<String> targetMemberships;

    public Relationship() {
        super();
    }

	public ConceptDescriptor getType() {
		return type;
	}

	public void setType(ConceptDescriptor type) {
		this.type = type;
	}

	public ConceptDescriptor getTarget() {
		return target;
	}

	public void setTarget(ConceptDescriptor target) {
		this.target = target;
	}

	public String getSourceId() {
		return sourceId;
	}

	public void setSourceId(String sourceId) {
		this.sourceId = sourceId;
	}

	public Integer getGroupId() {
		return groupId;
	}

	public void setGroupId(Integer groupId) {
		this.groupId = groupId;
	}

	public ConceptDescriptor getCharType() {
		return charType;
	}

	public void setCharType(ConceptDescriptor charType) {
		this.charType = charType;
	}

	public String getModifier() {
		return modifier;
	}

	public void setModifier(String modifier) {
		this.modifier = modifier;
	}

    public List<String> getTypeInferredAncestors() {
        return typeInferredAncestors;
    }

    public void setTypeInferredAncestors(List<String> typeInferredAncestors) {
        this.typeInferredAncestors = typeInferredAncestors;
    }

    public List<String> getTypeStatedAncestors() {
        return typeStatedAncestors;
    }

    public void setTypeStatedAncestors(List<String> typeStatedAncestors) {
        this.typeStatedAncestors = typeStatedAncestors;
    }

    public List<String> getTargetInferredAncestors() {
        return targetInferredAncestors;
    }

    public void setTargetInferredAncestors(List<String> targetInferredAncestors) {
        this.targetInferredAncestors = targetInferredAncestors;
    }

    public List<String> getTargetStatedAncestors() {
        return targetStatedAncestors;
    }

    public void setTargetStatedAncestors(List<String> targetStatedAncestors) {
        this.targetStatedAncestors = targetStatedAncestors;
    }

	public List<String> getTargetMemberships() {
		return targetMemberships;
	}

	public void setTargetMemberships(List<String> targetMemberships) {
		this.targetMemberships = targetMemberships;
	}
} public class ResourceSetManifest implements Serializable {

    private String resourceSetName;
    private String effectiveTime;
    private String databaseName;
    private String collectionName;
    private String expirationDate;
    private List<ConceptDescriptor> modules;
    private List<ConceptDescriptor> languageRefsets;
    private List<RefsetDescriptor> refsets;
    private Map<String, String> languageRefsetsAbbrev;
    private String defaultTermLangCode;
    private String defaultTermType;
    private String defaultTermLangRefset;
    private boolean textIndexNormalized;

    public ResourceSetManifest() {
        modules = new ArrayList<ConceptDescriptor>();
        languageRefsets = new ArrayList<ConceptDescriptor>();
        refsets = new ArrayList<RefsetDescriptor>();
        languageRefsetsAbbrev = new HashMap<String, String>();
    }

    public String getResourceSetName() {
        return resourceSetName;
    }

    public void setResourceSetName(String resourceSetName) {
        this.resourceSetName = resourceSetName;
    }

    public String getEffectiveTime() {
        return effectiveTime;
    }

    public void setEffectiveTime(String effectiveTime) {
        this.effectiveTime = effectiveTime;
    }

    public String getDatabaseName() {
        return databaseName;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }

    public String getCollectionName() {
        return collectionName;
    }

    public void setCollectionName(String collectionName) {
        this.collectionName = collectionName;
    }

    public String getExpirationDate() {
        return expirationDate;
    }

    public void setExpirationDate(String expirationDate) {
        this.expirationDate = expirationDate;
    }

    public List<ConceptDescriptor> getModules() {
        return modules;
    }

    public void setModules(List<ConceptDescriptor> modules) {
        this.modules = modules;
    }

    public List<ConceptDescriptor> getLanguageRefsets() {
        return languageRefsets;
    }

    public void setLanguageRefsets(List<ConceptDescriptor> languageRefsets) {
        this.languageRefsets = languageRefsets;
    }

    public List<RefsetDescriptor> getRefsets() {
        return refsets;
    }

    public void setRefsets(List<RefsetDescriptor> refsets) {
        this.refsets = refsets;
    }

    public Map<String, String> getLanguageRefsetsAbbrev() {
        return languageRefsetsAbbrev;
    }

    public void setLanguageRefsetsAbbrev(Map<String, String> languageRefsetsAbbrev) {
        this.languageRefsetsAbbrev = languageRefsetsAbbrev;
    }

    public String getDefaultTermLangCode() {
        return defaultTermLangCode;
    }

    public void setDefaultTermLangCode(String defaultTermLangCode) {
        this.defaultTermLangCode = defaultTermLangCode;
    }

    public String getDefaultTermType() {
        return defaultTermType;
    }

    public void setDefaultTermType(String defaultTermType) {
        this.defaultTermType = defaultTermType;
    }

    public String getDefaultTermLangRefset() {
        return defaultTermLangRefset;
    }

    public void setDefaultTermLangRefset(String defaultTermLangRefset) {
        this.defaultTermLangRefset = defaultTermLangRefset;
    }

    public boolean isTextIndexNormalized() {
        return textIndexNormalized;
    }

    public void setTextIndexNormalized(boolean textIndexNormalized) {
        this.textIndexNormalized = textIndexNormalized;
    }
} public class TextIndexDescription extends Description {
    
    private String fsn;
    private String semanticTag;
    private boolean conceptActive;
    private String typeId;
    private List<String> refsetIds;
    String definitionStatus;

    public TextIndexDescription() {
    }
    
    private String conceptModule;

	public String getConceptModule() {
		return conceptModule;
	}

	public void setConceptModule(String conceptModule) {
		this.conceptModule = conceptModule;
	}
    public String getFsn() {
        return fsn;
    }

    public void setFsn(String fsn) {
        this.fsn = fsn;
    }

    public String getSemanticTag() {
        return semanticTag;
    }

    public void setSemanticTag(String semanticTag) {
        this.semanticTag = semanticTag;
    }

    public boolean isConceptActive() {
        return conceptActive;
    }

    public void setConceptActive(boolean conceptActive) {
        this.conceptActive = conceptActive;
    }

    public String getTypeId() {
        return typeId;
    }

    public void setTypeId(String typeId) {
        this.typeId = typeId;
    }

    public List<String> getRefsetIds() {
        return refsetIds;
    }

    public void setRefsetIds(List<String> refsetIds) {
        this.refsetIds = refsetIds;
    }

    public String getDefinitionStatus() {
        return definitionStatus;
    }

    public void setDefinitionStatus(String definitionStatus) {
        this.definitionStatus = definitionStatus;
    }
} public class FileHelper {
	
	private static final Logger log = Logger.getLogger(FileHelper.class);
	
	
	public static int countLines(File file, boolean firstLineHeader) throws IOException {

		FileInputStream fis = new FileInputStream(file);
		InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
		LineNumberReader reader = new LineNumberReader(isr);
		int cnt = 0;
		String lineRead = "";
		while ((lineRead = reader.readLine()) != null) {
		}
		
		cnt = reader.getLineNumber();
		reader.close();
		isr.close();
		fis.close();
		if(firstLineHeader){
			return cnt-1;
		}else{
			return cnt;
		}
	}

	public void findSimpleRefsetFiles(File releaseFolder,String stringKey,String nocontains, HashSet< String> hashSimpleRefsetList) {
		String name="";
		if (hashSimpleRefsetList==null){
			hashSimpleRefsetList=new HashSet<String>();
			
		}
		for (File file:releaseFolder.listFiles()){
			if (file.isDirectory()){
				findSimpleRefsetFiles(file, stringKey,nocontains,hashSimpleRefsetList);
			}else{
				name=file.getName().toLowerCase().trim().replaceAll("-","_");
				if (name.endsWith(".txt") 
						&& name.contains(stringKey)){ 
						
						if (nocontains!=null && !name.contains(nocontains)  ){
							hashSimpleRefsetList.add(file.getAbsolutePath());
						}
				}
			}
		}

	}


	public void findAllFiles(File releaseFolder, HashSet< String> hashSimpleRefsetList) {
		String name="";
		if (hashSimpleRefsetList==null){
			hashSimpleRefsetList=new HashSet<String>();
			
		}
		for (File file:releaseFolder.listFiles()){
			if (file.isDirectory()){
				findAllFiles(file, hashSimpleRefsetList);
			}else{
				name=file.getName();
				if (name.endsWith(".txt")){ 
					hashSimpleRefsetList.add(file.getAbsolutePath());
				}
			}
		}

	}
	
	public static String getFileTypeByHeader(File inputFile) {
		String namePattern =null;
		try {
			Thread currThread = Thread.currentThread();
			if (currThread.isInterrupted()) {
				return null;
			}
			XMLConfiguration xmlConfig = new XMLConfiguration(ClassLoader.getSystemResource("validation-rules.xml"));
			List<String> namePatterns = new ArrayList<String>();

			Object prop = xmlConfig.getProperty("files.file.fileType");
			if (prop instanceof Collection) {
				namePatterns.addAll((Collection) prop);
			}
//			System.out.println("");
			boolean toCheck = false;
			String headerRule = null;
			FileInputStream fis = new FileInputStream(inputFile);
			InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
			BufferedReader br = new BufferedReader(isr);
			String header = br.readLine();
			for (int i = 0; i < namePatterns.size(); i++) {
				if (currThread.isInterrupted()) {
					return null;
				}
				headerRule = xmlConfig.getString("files.file(" + i + ").headerRule.regex");
				namePattern = namePatterns.get(i);
				if( header.matches(headerRule)){
					if ((inputFile.getName().toLowerCase().contains("textdefinition") 
							&& namePattern.equals("rf2-descriptions")) 
							|| (inputFile.getName().toLowerCase().contains("description") 
									&& namePattern.equals("rf2-textDefinition"))){
						continue;
					}
					toCheck = true;
					break;
				}
			}
			if (toCheck) {

				
				 //System.out.println( "File: " + inputFile.getAbsolutePath() +  " ** match file pattern: " + namePattern);
				
			} else {
				
				//System.out.println( "Cannot found header matcher for : " + inputFile.getName());
			}
			br.close();
		} catch (FileNotFoundException e) {
			System.out.println(  "FileAnalizer: " +    e.getMessage());
		} catch (UnsupportedEncodingException e) {
			System.out.println(  "FileAnalizer: " +    e.getMessage());
		} catch (IOException e) {
			System.out.println(  "FileAnalizer: " +    e.getMessage());
		} catch (ConfigurationException e) {
			System.out.println(  "FileAnalizer: " +    e.getMessage());
		}
		return namePattern;
	}

	public static void emptyFolder(File folder){
		if(folder.isDirectory()){
			File[] files = folder.listFiles();
			for (File file : files) {
				if(file.isDirectory()){
					emptyFolder(file);
				}else{
					file.delete();
				}
			}
		}
	}

	public static void copyTo(File inputFile,File outputFile)  throws IOException {

		FileInputStream fis = new FileInputStream(inputFile);
		InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
		LineNumberReader reader = new LineNumberReader(isr);
		

		FileOutputStream fos = new FileOutputStream( outputFile);
		OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
		BufferedWriter bw = new BufferedWriter(osw);
		
		String lineRead = "";
		while ((lineRead = reader.readLine()) != null) {
			bw.append(lineRead);
			bw.append("\r\n");
		}
		reader.close();
		bw.close();
			
	}
} public class TClosure {
	
//	HashMap<Long,HashSet<Long>>parentHier;
	HashMap<Long,HashSet<Long>>childrenHier;
//	private long ISARELATIONSHIPTYPEID=116680003l;
	private String ISA_SCTID="116680003";
	private String ROOT_CONCEPT = "138875005";
	String rf2Rels;
	private HashSet<Long> hControl;
	public TClosure(String rf2Rels) throws FileNotFoundException, IOException{
//		parentHier=new HashMap<Long,HashSet<Long>>();
		childrenHier=new HashMap<Long,HashSet<Long>>();
		this.rf2Rels=rf2Rels;
		loadIsas();
	}
	public TClosure(Map<String, List<LightRelationship>> relationships,String charType) throws FileNotFoundException, IOException {

//		parentHier=new HashMap<Long,HashSet<Long>>();
		childrenHier=new HashMap<Long,HashSet<Long>>();
		loadIsasFromMap(relationships, charType);
	}
	private void loadIsasFromMap(Map<String, List<LightRelationship>> relationships,String charType) {

		List<LightRelationship> listLR = new ArrayList<LightRelationship>();
		
		for (String cptId:relationships.keySet()){
			listLR = relationships.get(cptId);
			if (listLR != null) {
				for (LightRelationship lrel : listLR) {
					if (lrel.getCharType().equals(charType) &&
							lrel.getType().equals(ISA_SCTID) &&
							lrel.isActive()) {
	
						addRel(Long.parseLong(lrel.getTarget()),Long.parseLong(cptId));
					}
				}
			}
		}
	}
		
	private void loadIsas() throws IOException, FileNotFoundException {
		System.out.println("Starting Isas Relationships from: " + rf2Rels);
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(rf2Rels), "UTF8"));
		try {
			String line = br.readLine();
			line = br.readLine(); // Skip header
			int count = 0;
			while (line != null) {
				if (line.isEmpty()) {
					continue;
				}
				String[] columns = line.split("\\t");
				if (columns[7].equals(ISA_SCTID) 
						&& columns[2].equals("1") 
						&& !columns[4].equals(ROOT_CONCEPT)){
					addRel(Long.parseLong(columns[5]),Long.parseLong(columns[4]));
					
					count++;
					if (count % 100000 == 0) {
						System.out.print(".");
					}
				}
				line = br.readLine();
			}
			System.out.println(".");
//			System.out.println("Parent isas Relationships loaded = " + parentHier.size());
			System.out.println("Children isas Relationships loaded = " + childrenHier.size());
		} finally {
			br.close();
		}		
	}
	public void addRel(Long parent, Long child){
		if (parent==child){
			System.out.println("same child and parent: " + child);
			return;
		}
//		HashSet<Long> parentList=parentHier.get(child);
//		if (parentList==null){
//			parentList=new HashSet<Long>();
//		}
//		parentList.add(parent);
//		parentHier.put(child, parentList);
		
		HashSet<Long> childrenList=childrenHier.get(parent);
		if (childrenList==null){
			childrenList=new HashSet<Long>();
		}
		childrenList.add(child);
		childrenHier.put(parent, childrenList);
	}
	
//	public boolean isAncestorOf(Long ancestor,Long descendant){
//		
//		HashSet<Long>parent=parentHier.get(descendant);
//		if (parent==null){
//			return false;
//		}
//		if (parent.contains(ancestor)){
//			return true;
//		}
//		for(Long par:parent){
//			if (isAncestorOf(ancestor,par)){
//				return true;
//			}
//		}
//		return false;
//	}
	
//	public HashSet<Long> getParent(Long conceptId) {
//		return parentHier.get(conceptId);
//	}

	public HashSet<Long> getChildren(Long conceptId) {
		return childrenHier.get(conceptId);
	}
	public int getDescendantsCount(Long conceptId){

		hControl = new HashSet<Long>();
		int ret=getDistinctChildrenCount(conceptId);
		hControl=null;
		return ret;
	}
	private int getDistinctChildrenCount(Long conceptId){
		HashSet<Long> children=childrenHier.get(conceptId);
		if (children==null){
			return 0;
		}
		int ret=0;
		for(Long child:children){
			if (!hControl.contains(child)){
				hControl.add(child);
				ret++;
			
				ret+=getDistinctChildrenCount(child);
			}
		}		
		return ret;
	}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.ihtsdo.json.model.Concept;
import org.ihtsdo.json.model.ConceptDescriptor;
import org.ihtsdo.json.model.Description;
import org.ihtsdo.json.model.LangMembership;
import org.ihtsdo.json.model.LightDescription;
import org.ihtsdo.json.model.LightLangMembership;
import org.ihtsdo.json.model.LightRefsetMembership;
import org.ihtsdo.json.model.LightRelationship;
import org.ihtsdo.json.model.RefsetDescriptor;
import org.ihtsdo.json.model.RefsetMembership;
import org.ihtsdo.json.model.Relationship;
import org.ihtsdo.json.model.ResourceSetManifest;
import org.ihtsdo.json.model.TextIndexDescription;
import org.ihtsdo.json.utils.FileHelper;
import org.ihtsdo.json.utils.TClosure;
import org.mapdb.DBMaker;
import com.google.gson.Gson;
					LightRefsetMembership loopMember = new LightRefsetMembership();
					loopMember.setType(LightRefsetMembership.RefsetMembershipType.SIMPLEMAP.name());
					loopMember.setUuid(UUID.fromString(columns[0]));

					loopMember.setActive(columns[2].equals("1"));
					loopMember.setEffectiveTime(columns[1]);
					loopMember.setModule(columns[3]);
                    modulesSet.add(columns[3]);
					String sourceId = columns[5];
					loopMember.setReferencedComponentId(sourceId);
					loopMember.setRefset(columns[4]);
                    refsetsSet.add(columns[4]);
                    refsetsTypes.put(columns[4], LightRefsetMembership.RefsetMembershipType.SIMPLEMAP.name());

                    loopMember.setOtherValue(columns[6]);

					List<LightRefsetMembership> list = simpleMapMembers.get(sourceId);
					if (list == null) {
						list = new ArrayList<LightRefsetMembership>();
					}
					list.add(loopMember);
					simpleMapMembers.put(sourceId, list);

                    if (!refsetsCount.containsKey(loopMember.getRefset())) {
                        refsetsCount.put(loopMember.getRefset(), 0);
                    }
                    refsetsCount.put(loopMember.getRefset(), refsetsCount.get(loopMember.getRefset()) + 1);

                    count++;
					if (count % 100000 == 0) {
						System.out.print(".");
					}
				}
				line = br.readLine();
			}
			System.out.println(".");
			System.out.println("SimpleMap RefsetMember loaded = " + simpleMapMembers.size() + " (" + count + ")");
		} finally {
			br.close();
		}
	}

	public void loadLanguageRefsetFile(File languageRefsetFile, List<String> modulesToIgnore) throws FileNotFoundException, IOException {
		System.out.println("Starting Language Refset Members: " + languageRefsetFile.getName());
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(languageRefsetFile), "UTF8"));
		try {
			String line = br.readLine();
			line = br.readLine(); // Skip header
			int count = 0;
			while (line != null) {
				if (line.isEmpty()) {
                    line = br.readLine();
					continue;
				}
				String[] columns = line.split("\\t");
                if (modulesToIgnore.contains(columns[3])) {
                    line = br.readLine();
                    continue;
                }
				if (columns[2].equals("1")) {
					LightLangMembership loopMember = new LightLangMembership();
					loopMember.setUuid(UUID.fromString(columns[0]));

					loopMember.setActive(columns[2].equals("1"));
					loopMember.setEffectiveTime(columns[1]);
					loopMember.setModule(columns[3]);
                    modulesSet.add(columns[3]);
					String sourceId = columns[5];
					loopMember.setDescriptionId(sourceId);
					loopMember.setRefset(columns[4]);
                    langRefsetsSet.add(columns[4]);

                    loopMember.setAcceptability(columns[6]);
					List<LightLangMembership> list = languageMembers.get(sourceId);
					if (list == null) {
						list = new ArrayList<LightLangMembership>();
					}
					list.add(loopMember);
					languageMembers.put(sourceId, list);
					count++;
					if (count % 100000 == 0) {
						System.out.print(".");
					}
				}
				line = br.readLine();
			}
			System.out.println(".");
			System.out.println("LanguageMembers loaded = " + languageMembers.size() + " (" + count + ")");
		} finally {
			br.close();
		}
	}

	public void createConceptsJsonFile(String fileName, boolean createCompleteVersion) throws FileNotFoundException, UnsupportedEncodingException, IOException {
		System.out.println("Starting creation of " + fileName);
        getCharConvTable();
		FileOutputStream fos = new FileOutputStream(fileName);
		OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
		BufferedWriter bw = new BufferedWriter(osw);
		Gson gson = new Gson();

		List<LightDescription> listLD = new ArrayList<LightDescription>();
		List<Description> listD = new ArrayList<Description>();

		List<LightLangMembership> listLLM = new ArrayList<LightLangMembership>();
		List<LangMembership> listLM = new ArrayList<LangMembership>();

		List<LightRelationship> listLR = new ArrayList<LightRelationship>();
		List<Relationship> listR = new ArrayList<Relationship>();

		List<LightRefsetMembership> listLRM = new ArrayList<LightRefsetMembership>();
		List<RefsetMembership> listRM = new ArrayList<RefsetMembership>();

        int count = 0;
        boolean firstWritten = false;
		for (String cptId : concepts.keySet()) {
            count++;
            if (count % 10000 == 0) {
                System.out.print(".");
            }
			Concept cpt = new Concept();