protected Area buildArea(final XMLTag piece, final Map<String,Object> defined, int direction) throws CMException
	{
		defined.put("DIRECTION",CMLib.directions().getDirectionName(direction).toLowerCase());

		final String classID = findStringNow("class",piece,defined);
		final Area A = CMClass.getAreaType(classID);
		if(A == null)
			throw new CMException("Unable to build area on classID '"+classID+"', Data: "+CMParms.toKeyValueSlashListString(piece.parms())+":"+CMStrings.limit(piece.value(),100));
		defined.put("AREA_CLASS",classID);
		final String name = findStringNow(A,null,"AREA_","NAME",piece,defined);
		if(CMLib.map().getArea(name)!=null)
		{
			A.destroy();
			throw new CMException("Unable to create area '"+name+"', you must destroy the old one first.");
		}
		A.setName(name);
		defined.put("AREA_NAME",name);
		
		PostProcessAttempter(defined,new PostProcessAttempt() {
			@Override
			public String attempt() throws CMException, PostProcessException 
			{
				final String author = findOptionalString(A,null,"AREA_","author",piece,this.defined, false);
				if(author != null)
				{
					A.setAuthorID(author);
					defined.put("AREA_AUTHOR",author);
				}
				return author;
			}
		});
		PostProcessAttempter(defined,new PostProcessAttempt() {
			@Override
			public String attempt() throws CMException, PostProcessException 
			{
				final String description = findOptionalString(A,null,"AREA_","description",piece,this.defined, false);
				if(description != null)
				{
					A.setDescription(description);
					defined.put("AREA_DESCRIPTION",description);
				}
				return description;
			}
		});
		
		if(fillInArea(piece, defined, A, direction))
			return A;
		throw new CMException("Unable to build area for some reason.");
	}